Skip to content

Latest commit

 

History

History
240 lines (183 loc) · 9.59 KB

android-connects-mqtt-using-kotlin.md

File metadata and controls

240 lines (183 loc) · 9.59 KB

MQTT is a lightweight and flexible protocol for exchanging IoT messages and delivering data. It is used to achieve a balance between flexibility and hardware/internet resources for IoT developers.

Kotlin is a programming language developed by JetBrains. Kotlin is based on the JVM, so developers can easily use it for Android development, and it supports mixed writing of Kotlin and Java.

This article mainly introduces how to use Kotlin in the Android platform for using MQTT.

Project Initialization

Open Android Studio, create a new project, select Kotlin as the language, and then Android Studio will automatically create the related configurations to Kotlin. If you need to configure the existing projects, can refer to Add Kotlin to an existing app.

Add dependency

Open build.gradle of the project, add dependencies Eclipse Paho Java Client and Eclipse Paho Android Service to the section dependencies.

dependencies {
    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.4'
    implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1' 
}

Configure AndroidManifest.xml

Android Service is a backend service, based on Android and developed by Eclipse. We need to register it to the file AndroidManifest.xml. Meanwhile, we also need to register the permission.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
   ...
   <service android:name="org.eclipse.paho.android.service.MqttService" />
</application>

Using MQTT

Create MQTT client

private lateinit var mqttClient: MqttAndroidClient
// TAG
companion object {
    const val TAG = "AndroidMqttClient"
}

Connect to the MQTT broker

This article will use the MQTT broker which is operated and maintained by EMQX MQTT Cloud. EMQX Cloud is the MQTT IoT cloud service platform released by EMQ, it provides the service for accessing MQTT 5.0 with all-in-one operation and maintenance and unique isolation environment.

  • Broker: broker.emqx.io
  • TCP Port: 1883
  • Websocket Port: 8083
Open Manufacturing Hub
A Practical Guide to MQTT Broker Selection
Download this practical guide and learn what to consider when choosing an MQTT broker.
Get the eBook →
fun connect(context: Context) {
        val serverURI = "tcp://broker.emqx.io:1883"
        mqttClient = MqttAndroidClient(context, serverURI, "kotlin_client")
        mqttClient.setCallback(object : MqttCallback {
            override fun messageArrived(topic: String?, message: MqttMessage?) {
                Log.d(TAG, "Receive message: ${message.toString()} from topic: $topic")
            }

            override fun connectionLost(cause: Throwable?) {
                Log.d(TAG, "Connection lost ${cause.toString()}")
            }

            override fun deliveryComplete(token: IMqttDeliveryToken?) {

            }
        })
        val options = MqttConnectOptions()
        try {
            mqttClient.connect(options, null, object : IMqttActionListener {
                override fun onSuccess(asyncActionToken: IMqttToken?) {
                    Log.d(TAG, "Connection success")
                }

                override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
                    Log.d(TAG, "Connection failure")
                }
            })
        } catch (e: MqttException) {
            e.printStackTrace()
        }

    }

The interface MqttCallback includes three methods:

  1. messageArrived: receive new messages from the broker
  2. connectionLost: lost the connection to the broker
  3. deliveryComplete: complete message delivery to the broker

MqttConnectOptions is used to configure connection settings including users' password, timeout configuration, etc. Please view its function for details.

Create an MQTT subscription

Subscribe topic

fun subscribe(topic: String, qos: Int = 1) {
        try {
            mqttClient.subscribe(topic, qos, null, object : IMqttActionListener {
                override fun onSuccess(asyncActionToken: IMqttToken?) {
                    Log.d(TAG, "Subscribed to $topic")
                }

                override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
                    Log.d(TAG, "Failed to subscribe $topic")
                }
            })
        } catch (e: MqttException) {
            e.printStackTrace()
        }
    }

Unsubscription

fun unsubscribe(topic: String) {
        try {
            mqttClient.unsubscribe(topic, null, object : IMqttActionListener {
                override fun onSuccess(asyncActionToken: IMqttToken?) {
                    Log.d(TAG, "Unsubscribed to $topic")
                }

                override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
                    Log.d(TAG, "Failed to unsubscribe $topic")
                }
            })
        } catch (e: MqttException) {
            e.printStackTrace()
        }
    }

Publish messages

fun publish(topic: String, msg: String, qos: Int = 1, retained: Boolean = false) {
        try {
            val message = MqttMessage()
            message.payload = msg.toByteArray()
            message.qos = qos
            message.isRetained = retained
            mqttClient.publish(topic, message, null, object : IMqttActionListener {
                override fun onSuccess(asyncActionToken: IMqttToken?) {
                    Log.d(TAG, "$msg published to $topic")
                }

                override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
                    Log.d(TAG, "Failed to publish $msg to $topic")
                }
            })
        } catch (e: MqttException) {
            e.printStackTrace()
        }
    }

Disconnect from the MQTT Broker

fun disconnect() {
        try {
            mqttClient.disconnect(null, object : IMqttActionListener {
                override fun onSuccess(asyncActionToken: IMqttToken?) {
                    Log.d(TAG, "Disconnected")
                }

                override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
                    Log.d(TAG, "Failed to disconnect")
                }
            })
        } catch (e: MqttException) {
            e.printStackTrace()
        }
    }

Test

Firstly, you need to connect the Android client to the MQTT broker then subscribe topic: a/b, and then you can see the log of successfully connecting and subscribing.

MQTT connect and subscribe

We test with MQTT 5.0 client tool - MQTTX, publish messages to the topic: a/b, and then we can see the log of receiving messages on the client.

MQTT 5.0 Client Tool  MQTTX

receive MQTT messages

We publish messages on the client to the topic: a/b. Because we subscribed to this topic, we will also receive the message at the same time. Finally, we disconnect the client from the MQTT broker. The log is as below:

publish mqtt message and disconnect

Summary

So far, we have finished the construction of the MQTT client on the Android and implemented the connection between the client and MQTT broker, subscribing topics, messaging, etc.

MQTT can provide real-time and reliable message service for connecting remote devices, only with a few codes and limited bandwidth. Since it is a kind of low-cost, low-bandwidth occupancy instant communicating protocol, it is widely used for IoT, small-size equipment, mobile applications, etc.

Next, you can check out The Easy-to-understand Guide to MQTT Protocol series of articles provided by EMQ to learn about MQTT protocol features, explore more advanced applications of MQTT, and get started with MQTT application and service development.

Try EMQX Cloud for Free
No credit card required
Get Started →