Back to all

Getting started with MQTT on Android using Mosquitto

The demand for real-time communication has become critical in the evolving landscape of mobile applications. Whether it’s instant messaging, live updates, or sensor data streaming, the need for fast and efficient data exchange is undeniable. Here is where MQTT emerges as a powerful solution. MQTT’s efficiency lies in its minimal overhead and ability to handle unreliable networks, making it ideal for resource-constrained devices and ensuring low-latency communication in dynamic mobile application environments. 

This guide will show how to exploit the capabilities of MQTT in Android development, using MQTT Paho libraries. By the end, you will have the knowledge and tools to integrate MQTT seamlessly into your Android projects.

Combining Mosquitto and Android

To demonstrate the integration between Android and Mosquitto, I will create a small Android application that enables testing basic MQTT functionalities, like publishing and subscribing.

The application will interact with an MQTT client (hosted by a PC) via the broker. The Mosquitto broker will act as an intermediary between the two clients, enabling them to exchange MQTT data by facilitating publishing and subscribing operations. Figure 1 below shows the setup of the project.

Project setup involving an MQTT client, a Mosquitto broker, and the Android application.
Figure 1 – Project setup: a Mosquitto Broker, an MQTT client, and the Android application.

The application consists of two different Android activities

  • The first allows the authentication process
  • The second allows basic MQTT operations, like publish, subscribe, unsubscribe, and disconnect.

For this project, I will use the on-premises version of Pro Mosquitto, which will run on a docker container, for which you can find a detailed setup guide here.

The Pro edition of the well-known Mosquitto MQTT broker includes an extended set of functionalities. If you want to know about the advantages of using the pro version, you can refer to this comparison.

Mosquitto and Android: the project setup

The process of setting up the project environment will involve installing and running Android Studio and the Pro Mosquitto MQTT broker.

Getting Android Studio

Android Studio is the official and most used development environment for Android. It supports different programming languages such as Java, Kotlin, and C++. This project will utilize Kotlin, currently the preferred Google language for Android application development.

First, download and install Android Studio.

Android Studio graphical user interface.
Figure 2 – The Android Studio IDE.

The graphical user interface is intuitively designed with a view of the project resources on the left side, and the code editor for writing the Kotlin program in the center. In the top right corner of the interface is a debugging options bar with some relevant settings.

Debugging menu in the top right corner of the Android Studio IDE.
Figure 3 – Debugging menu bar.

Apart from the classical start/stop program execution and debugging buttons, Android Studio specifies a target hardware to test the application under development. The target hardware can be a physical Android phone or a virtual emulated device.

In the “Coding the Android application” section, I will show how to use Android Studio to create a new project and to utilize the debugging features.

Configuring the Mosquitto MQTT Broker

I will use the on-premises trial license of the latest Pro Edition of Eclipse Mosquito for this article. You can request a free 30-day trial period here, which includes basic MQTT HA configuration and access to advanced features.

The Pro Mosquitto configuration is straightforward since it will only consist of a client creation. Start the Mosquitto Management Center by logging in through the dashboard at: http://localhost:8088/.

The following dashboard should appear:

Mosquitto Management Center (MMC) dashboard for Pro Mosquitto.
Figure 4 – MMC dashboard for Pro Mosquitto monitoring.

Click the client icon on the left bar to open the client configuration menu, then on the “New Client” button to open the client creation panel:

Client creation panel in the Mosquitto Management Center.
Figure 5 – Client creation panel.

Create a client with the username “Android,” set the password to “android_pwd,” and click on save to create the client.

Now, I can set the specific role to “client.”

Set the specific Android user role to "client."
Figure 6 – Set the Android user role to “client.”

With the configuration now complete, the next chapter shows how to integrate MQTT into the Android application.

Coding the Android application

This tutorial assumes the user is familiar with Android development. Therefore, I will only provide details for parts of the application creation process. I will only show relevant snippets of the application code to help users get the MQTT integration running.

Starting with Android Studio, create a new project by selecting the “Empty Activity” template.

Select the "Empty Activity" template to create a new project.
Figure 7 – New project creation.

The application will use two activities, the one already existing for user authentication and the second (to be created) for the publishing and subscribing functionality. 

This project uses the Paho Library, one of the most prominent MQTT libraries available for different platforms and languages.

Integrating the MQTT Libraries

Integrating the MQTT Paho libraries into Android Studio is a straightforward process. However, a short explanation can help execute this task without issues.

It’s also worth mentioning that this procedure is currently valid for Android Studio Giraffe 2022.3.1. The process can vary for older Android Studio versions, especially concerning the correct syntax for integrating repositories and packages.

First of all, it is necessary to add the following two dependencies into the project gradle file:

implementation("org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0")
implementation("org.eclipse.paho:org.eclipse.paho.android.service:1.1.1")

In the gradle settings (settings.gradle.kts), add a reference to the original repository:

dependencyResolutionManagement {
   repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
   repositories {
       google()
       mavenCentral()
       maven {url = uri("https://repo.eclipse.org/content/repositories/paho-releases/") }

Finally, update the AndroidManifest.xml file by adding the Paho library services,

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

and the required permission the application must have to allow the MQTT service to run:

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

After performing these steps, the Paho libraries integration is complete.

Start the MQTT communication: the connect function

After integrating the MQTT Paho library, let’s proceed with organizing the relevant code in different Kotlin functions.

It’s worth mentioning that the functions will use a globally defined MqttAndroidClient object with the name mqttClient, instantiated inside the connect function. This object will carry the MQTT client instantiation. The first function to implement is the mqttConnect, which performs the client connection toward the broker.

The function requires the broker address, the client username, and the client password as arguments. The username and password will be handled through a MqttConnectOptions object.

Finally, the connect method of the object mqttClient performs the connection. Two mqttClient methods are overridden, allowing the execution of some specific code based on the connection’s success or failure.

fun mqttConnect(applicationContext: Context, brokeraddr: String, clientuser: String, clientpwd: String) {
   // ClientId is a unique id used to identify a client
   val clientId = MqttClient.generateClientId()


   // Create an MqttAndroidClient instance
   mqttClient = MqttAndroidClient ( applicationContext, "tcp://$brokeraddr", clientId )


   // ConnectOption is used to specify username and password
   val connOptions = MqttConnectOptions()
   connOptions.userName = clientuser
   connOptions.password = clientpwd.toCharArray()


   try {
       // Perform connection
       mqttClient.connect(connOptions, null, object : IMqttActionListener {
           override fun onSuccess(asyncActionToken: IMqttToken)                        {
               // Add here code executed in case of successful connection
           }override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
               // Add here code executed in case of failed connection
               Log.d(“MqttClient”, “Connection failed”)
           }
       })
   } catch (e: MqttException) {
       // Get stack trace
       e.printStackTrace()
   }
}

Exchange data: MQTT Publish and Subscribe

Now that the application can connect, let’s take care of the publishing and subscribing functionalities. I will implement the following functions:

  • Listener for received messages
  • Subscribe
  • Publish
  • Unsubscribe

First, set up a listener for incoming messages. The mqttSetReceivedListener function allows configuring a callback that will be called every time a message is received over a subscribed topic. In my example, the callback will extract the payload of the received message and paste it into a textbox object.

fun mqttSetReceiveListener() {
   mqttClient.setCallback(object : MqttCallback {
       override fun connectionLost(cause: Throwable) {
           // Connection Lost
       }
       override fun messageArrived(topic: String, message: MqttMessage) {
            // A message has been received
            val data = String(message.payload, charset("UTF-8"))
            // Place the message into a specific TextBox object
            editTextRcvMsg.editText!!.setText(data)
       }
       override fun deliveryComplete(token: IMqttDeliveryToken) {
           // Delivery complete
       }
   })
}

After programming the listener, define the subscribe function mqttSubscribe. This function allows you to subscribe to a specific topic. Use the subscribe method of the mqttClient object to implement this functionality. The function will get the topic and quality of service as arguments.

fun mqttSubscribe(topic: String, qos: Int) {
   try {
       mqttClient.subscribe(topic, qos, null, object : IMqttActionListener {
           override fun onSuccess(asyncActionToken: IMqttToken) {
               // Successful subscribe
           }override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
               // Failed subscribe
           }
       })
   } catch (e: MqttException) {
       // Check error
   }
}

The next function to implement is the publish function (mqttPublish), which enables sending a message over a specific topic.

Message payload, topic, and quality of service are the arguments of this function. The publish method is used to publish the message.

fun mqttPublish(topic: String, msg: String, qos: Int) {
   try {
       val mqttMessage = MqttMessage(msg.toByteArray(charset("UTF-8")))
       mqttMessage.qos = qos
       mqttMessage.isRetained = false
       // Publish the message
       mqttClient.publish(topic, mqttMessage)
   } catch (e: Exception) {
       // Check exception
   }
}

Lastly, implement the unsubscribe function. This allows you to remove a specific topic from the subscribed topic list. To unsubscribe from a topic, use the unsubscribe method of the mqttClient object.

fun mqttUnsubscribe(topic: String) {
   try {
       // Unsubscribe from topic
       mqttClient.unsubscribe(topic, null, object : IMqttActionListener {
           override fun onSuccess(asyncActionToken: IMqttToken) {
               // Successful unsubscribe
           }override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
               // Failed unsubscribe
           }
       })
   } catch (e: MqttException) {
       // Check exception
   }
}

Close the connection: the MQTT disconnect function

At this point, the application can connect, publish, subscribe and unsubscribe. However, the possibility of closing the connection is still missing. To achieve this, you need to include the disconnect function.

The Paho libraries offer a disconnect method for this purpose.

fun mqttDisconnect() {
   try {
       mqttClient.disconnect(null, object : IMqttActionListener {
           override fun onSuccess(asyncActionToken: IMqttToken) {
               //Successful disconnection
           }
           override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
               //Failed disconnection
           }
       })
   } catch (e: MqttException) {
       // Check exception
   }
}

Testing the Android application

With the Android application complete, I can proceed with testing the main functions described.

To begin testing, first ensure that Pro Mosquitto is running and that the Android client is configured. Next, start the Android application, select the test device, and click the play button (Figure 8). The smartphone will start the application.

Click the play button to start the Android application.
Figure 8 – Start the application by clicking the play button (red square).

As shown in Figure 9, enter the broker address, username, and password on the Android application that was selected during the client creation process in Pro Mosquitto.

Enter the broker address, username, and password in the Android application screen.
Figure 9 – The first application screen allows you to enter the broker address, username, and password.

After inserting the necessary information, click the Authentication button to connect to the Pro Mosquitto broker. The button click will trigger the mqttConnect function.

Upon a successful connection, the application will switch to the second activity, allowing the testing of the publish and subscribe functionality. To test the publish function for this scope, set up a receiving subscriber client on your local PC. The client application used is based on the MQTT.js library, which requires installation of Node.js.

In a Windows PowerShell, start the subscriber using the following command:

npx mqtt subscribe -h 192.168.178.20 -t /topic/test -u Android -P android_pwd

With the Publish button (mqttPublish function), you can publish the message from the application, specifying the topic and the message, as in Figure 10.

Specify the topic and message to publish from the Android application.
Figure 10 – Message publishing.

The subscriber client receives the message (Figure 11).

The subscriber receives the message from the Android application.
Figure 11 – The subscriber receives “Message from Android”.

After testing the publish operation, you can test the subscribe function.

Specify the topic and click on the subscribe button (mqttSubscribe function) to let the application subscribe to the topic. Then, perform a publish test from the PC using the command:  

npx mqtt publish -h 192.168.178.20 -t /topic/test -u Android -P android_pwd -m Message from PC

The application will receive the message (Figure 12).

The application receives the message from the PC.
Figure 12 – The application receives the message “Message from PC”.

Finally, click the unsubscribe button to unsubscribe from the topic (mqttUnsubscribe function). This time, repeating the same publish command from the PC client will not cause the application to receive the message.

As a final step, you can close the connection by clicking the disconnect button (mqttDisconnect function).

Conclusion

Real-time communication is possible by connecting to a Mosquitto MQTT broker and exploring the integration of MQTT in an Android app.

The combination of MQTT Paho libraries and Mosquitto establishes a robust foundation for scalable Android applications, whether you are delving into IoT or enhancing real-time user engagement. Your Android app is now part of the ever-expanding network of smart, responsive, and connected applications. In conclusion, this integration transforms your app and opens doors for further innovation in mobile connectivity.

Click to rate this post!
[Total: 1 Average: 5]
About the author
Matteo Trovo Cedalo author

Matteo Trovò

Senior Embedded Software Engineer

Matteo Trovò is a seasoned embedded software engineer with extensive expertise in cybersecurity, computer networks, and data protocols, including MQTT. He is currently employed as a Senior Embedded Software Engineer in the automotive industry in Germany.

After completing a degree in Software Engineering, Matteo gained valuable experience working for various companies, honing his skills in practical settings. During this time, he also supported and contributed to a startup developing MQTT interconnected smart switches for home automation. As the software development lead, Matteo delved deep into MQTT, writing MQTT client software and managing MQTT device networks.

Newsletters icon

Subscribe for monthly updates