MQTT Client Library Encyclopedia – Paho Android Service

Guest post by Sandro Kock

Pahao Android Service
LanguageJava
LicenseEclipse Public License v1.0 and Eclipse Distribution License v1.0
Websitehttps://eclipse.org/paho/clients/android/
API StyleAsynchronous

Description

The Paho Android Service is an interface to the Paho Java MQTT Client library for the Android Platform. The MQTT connection is encapsulated within an Android-Service that runs in the background of the Android application, keeping it alive when the Android application is switching between different Activities. This layer of abstraction is needed to be able to receive MQTT messages reliably. As the Paho Android Service is based on the Paho Java client library it can be considered stable and used in production. The project is actively maintained by the Eclipse Paho project.

Features

MQTT 3.1ok
MQTT 3.1.1ok
LWTok
SSL/TLSnok
Automatic Reconnectnok (On the road map)
QoS 0ok
QoS 1ok
QoS 2ok
Authenticationok
Throttlingnok

Usage

Installation

Android uses Gradle as a build system and dependency management, therefor this blog post describes how the Paho Android Service can be added to an application via Gradle. The most convenient way to start a new Android Application is to use Android Studio. To add the Paho Android Service as a dependency to you app add the following parts to your gradle file.

The first part adds the Paho release repository to the gradle config, so that Gradle is able to find the packaged Paho Android Service JAR. The second part adds the Paho Android Service as a dependency to the application. The exclusion of the Android Support library exclude module: 'support-v4' is only necessary if the Android application is using the Android Support Library to backport newer Android features to older Android versions. To have the latest Snapshot release within your application the gradle config below can be used.

Connect

As already mentioned, the Paho Android Service encapsulates the MQTT connection and offers an API for that. To be able to create a binding to the Paho Android Service, the service needs to be declared in the AndroidManifest.xml. Add the following within the <application> tag:

The Paho Android Service needs the following permissions to work:

Add those to the <manifest> tag.

Usually an Android Activity requests or binds to an Android Service to use it, for e.g. the LocationManager to receive updates when the GPS position of the user changes. The Paho Android Service is not meant to bind to directly. Instead the provided MqttAndroidClient client interface binds to the service once created. To create and establish an MQTT-connection use the following code snipped:

In the first line a helper Function of the Paho MQTT client is used to generate a random user id. The second line creates an instance of an Android MQTT client, that will bind to the Paho Android Service. By calling the connect method of the MqttAndroidClient the client will asynchronously try to connect to the MQTT broker and return a token. That token can be used to register callbacks, to get notified when either the MQTT-connection gets connected or an error occurs. Running the above example inside an Android Activity.onCreate method will print “onSuccess” or “onFailure” to the console.

Connect with MQTT 3.1 or MQTT 3.1.1

The MqttAndroidClient will connect with MQTT 3.1.1 by default, with a fallback to 3.1. To intentionally connect with MQTT 3.1 a MqttConnectOptions object can be supplied to the connect method:

Connect with LWT

Like the MQTT version, the Last Will And Testament (LWT) can be added into the MqttConnectOptions object.

Besides the payload of the LWT, everything is straight forward and can be just set. Many MQTT clients assume that the payload is an UTF-8 formatted string and convert the payload automatically. The fact that MQTT is a binary protocol is often hidden with that. By calling String#getBytes the string will be encoded with the systems default charset (UTF-8 on Android).

Connect with Username / Password

Again like the MQTT version and the LWT, the username and password can be supplied within the options object.

Publish

The MqttAndroidClient allows messages to be published via its publish(topic, MqttMessage) method. By design the MqttAndroidClient dose not queue any messages if the client is not connected and will throw an error when trying to send messages when the client is offline client.isConnected() == false. After the first connect, the IMqttActionListener.onSuccess method is called when a MQTT connection is established successfully.

Publish a retained message

To send a retained MQTT message the MqttMessage.retained attribute can be set to true via MqttMessage.setRetained(true).

Subscribe

Subscriptions can be created via the MqttAndroidClient.subscribe method, which takes the topic and the QOS as parameters and returns a IMqttToken. The token can be used to keep track if the subscription can successfully established or failed. The example below subscribes to the topic “foo/bar” with QOS 1

Unsubscribe

Disconnect

To disconnect the client call the disconnect method of the MqttAndroidClient object. The example below saves the token returned by the disconnect method and adds a IMqttActionListener to get notified when the client is successfully disconnected.

Using SSL / TLS

When connecting with SSL/TLS the MQTT-broker has to use a valid certificate that is trusted via the chain of trust of the Android device or provide a custom Java SocketFactory. Currently I am not aware of any public MQTT broker that can be used to test a SSL/TLS connection without a custom SocketFactory, hopefully this will change in the near feature with Let’s Encrypt in place.

IoT Eclipse provides an MQTT Sandbox running MQTT encrypted on iot.eclipse.org:8883 and supports TLS 1.0, 1.1 and 1.2. Android on the other hand uses a cryptography API library called BouncyCastle. To generate a BouncyCastle keystore (BKS) on a development machine the BounceCastleProvider class is required in the JAVA-Classpath. The JAR containing the class can be downloaded here. To generate the BKS the JDK keytool can be used with the following parameters:

The command assumes that you saved the BouncyCastle JAR and the iot.eclipse.org.crt into the current directory. It will generate a BouncyCastle Keystore names iot.eclipse.org.bks with the password set to eclipse-password.

To actually use the keystore, create a folder named “assets” in the “src/main” directory of you app and copy the iot.eclipse.org.bks file into it. The following example will create a secure MQTT connection to the Eclipse test broker:

The example uses the utility function getSSLSocketFactory of the MqttAndroidClient to create a custom SocketFactory from the BKS keystore input stream.

Full example application

The Eclipse Paho project provides a very detailed example application that demonstrates the capabilities of the Paho Android Service. A packaged application is available at Paho Android Sample. The APK is based on the current development branch in the Eclipse repository. To clone the entire GIT repository use the following command:

The Android sample application source is located in the org.eclipse.paho.android.service/org.eclipse.paho.android.sample folder, that can be opened with Android Studio.

Author Information

sandro_kock
Sandro Kock
Since 2014 Sandro Kock is a mobile developer at SSV Software Systems, responsible for developing mobile solutions, with a focus on IoT/M2M. Before that he wrote the MQTT client MQTTlens, which is based on Polymer.

45 comments

  1. Ian Gough says:

    It may be worth mentioning for those unfamiliar with the Paho Android Service that you need to call client.setCallback() and implement MqttCallback in order to receive messages on the topics to which you subscribed.

    1. Yes. I was also looking for that here.

      I’ve added my subscription logic on the onSuccess method block:
      public void onSuccess(IMqttToken asyncActionToken) {
      // We are connected
      Log.d(TAG, “onSuccess”);
      subscribe(asyncActionToken);
      }

      Works, but seems strange to chain events like this?

    2. xs says:

      How to reconnect?

    3. vivek kumar verma says:

      Hello,
      I am trapped in a situation where i am trying to set different textview(to display message) for different subscribed topic.
      i.e let i am subscribed to two different topic and i am getting different messages on that different topic and i need to display those different subscribed topic message to the different text view.
      plz help

  2. viraj says:

    I tried executing the above steps in Android Studio, i also added jar files to libs even then i have the following errors:
    Error:(16, 27) error: cannot find symbol variable MqttClient
    Error:(18, 21) error: cannot find symbol class MqttAndroidClient
    Error:(17, 9) error: cannot find symbol class MqttAndroidClient
    Error:(22, 13) error: cannot find symbol class IMqttToken
    Error:(23, 41) error: cannot find symbol class IMqttActionListener
    please help!

    1. Hi Viraj,

      did you include the library? The errors does not seem to have anything to do with Paho itself, it seems that’s a dependency issue.

      All the best,
      Dominik from the HiveMQ Team

    2. thats because the example above is missing the second library in the dependencies directive of your gradle file
      compile(‘org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.3-SNAPSHOT’) {
      exclude module: ‘support-v4’
      }

    3. bytehala says:

      Hi viraj, were you able to solve the problem? It is indeed a dependency issue. Adding the jar files to libs is Step 1. After that, you need to make sure that the jars are included in the Build Path.

      Anyway, if you wanted to use Android Studio, please check out my github. The link is in one of the comments further down. Hope this helps.

  3. Dadan says:

    How to get message from a topic when I subscribe that topic ?

    1. Hi Dadan,

      you can set a MqttCallback via the setCallback method. You can find an example implementation of such a method here: https://github.com/eclipse/paho.mqtt.android/blob/master/org.eclipse.paho.android.sample/src/main/java/org/eclipse/paho/android/sample/activity/MqttCallbackHandler.java

      Hope this helps,
      Dominik

  4. I keep running into issues with this lib. I’ve tried both 1.0.2 and 1.0.3 (Android Service) and it just does not seem to work and not stable.

    for instance, and following your example above, I tried to get a boolean value from asynctoken.getSessionPresent() and the code blows up at run-time with a null exception, but the token itself is not null.

    Here’s the code:

    token.setActionCallback(new IMqttActionListener() {
    @Override
    public void onSuccess(IMqttToken asyncActionToken) {
    // We are connected
    Log.d(TAG, “onSuccess”);
    if(asyncActionToken == null){
    Log.d(TAG, “obj is null”);
    }
    else{
    Log.d(TAG, “not null – issession present? ” + asyncActionToken.getSessionPresent());
    }
    }

  5. Kalpesh says:

    It works on my emulator but does not work on a device

    1. bytehala says:

      Hi Kalpesh, I just published the Android Studio version of the Paho Android sample client on my Github: https://github.com/bytehala/android-mqtt-quickstart

      I was able to create an app for a client using it, so hopefully it will work on your device. Let me know if it helps.

  6. moshe says:

    hey is anybody else getting a NullPointer Exception when subscribing?
    could use some help..

    1. Hi moshe,

      A NullPointerException is often a sign that something wasn’t initialized as expected. The best way to get help with that if you believe that is a Paho Bug would be to raise an issue with Paho or check if there is a known issue with a workaround available. The Paho Issue Tracker can be found here: https://github.com/eclipse/paho.mqtt.java/issues

      Hope this helps,
      Dominik from the HiveMQ Team

  7. Dhanasekaran S says:

    It work for me

  8. Yasir says:

    Thank you for the fantastic tutorial, I was wondering if you could let me know how I can view the messages of the topic I have subscribed to? The way I have implemented it is that you press a button and it subscribes but I want to extend it so that it subscribes to the topic then displays the message.

  9. prakash says:

    how to get All Connected Client ID so that i can publish Message to all the connected client without subscribe.

    1. Hi Prakash,

      MQTT is designed as a publish/subscribe protocol and thus direct communication between clients is not possible without using subscription mechanisms. You can learn more about that in this blog post: http://www.hivemq.com/blog/mqtt-essentials-part2-publish-subscribe

      If you want to get all client identifiers you can use the plugin system of HiveMQ for that. Take a look at the ClientService: http://hivemq.com/docs/plugins/latest/#client-service

      Hope this helps,
      Dominik from the HiveMQ Team

  10. Andrea says:

    Hello,
    I managed to publish and subscribe but I really can’t understand how to listed for subscription message.

  11. Tal says:

    Hi,
    Thank you very much for this great tutorial!
    but, there is a problem cloning the Git repository of the example..
    I’ll be grateful if it would be fixed, since I have to see an example of the ‘gradle’ part.
    my project’s gradle doesn’t compile at all when i add the needed lines..
    Thank you in advance..!

  12. Frogec says:

    Hi,
    great tutorials and explanations on this website! Very well written and with a lot of nice examples.

    Thank you!

  13. Cuong Nguyen says:

    Hi
    My project has been working well by following the first way to install paho (the stable version: service:1.0.2). However, when I use the second way (using snapshot), it shows that the following cannot be imported:

    import org.eclipse.paho.client.mqttv3.IMqttActionListener;
    import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
    import org.eclipse.paho.client.mqttv3.IMqttToken;
    import org.eclipse.paho.client.mqttv3.MqttCallback;
    import org.eclipse.paho.client.mqttv3.MqttClient;
    import org.eclipse.paho.client.mqttv3.MqttException;
    import org.eclipse.paho.client.mqttv3.MqttMessage;

    1. Hi Cuong,

      Thanks for your comment.
      I would recommend to ask this question on the paho dev mailing list: https://dev.eclipse.org/mailman/listinfo/paho-dev

      Best regards,
      Christian from the HiveMQ Team

  14. Manish Prajapat says:

    Thank you so much .Worked smoothly

  15. Fabricio says:

    As I could handle the reconnection, I tried to disconnect and connect when the network goes and return respectively but when I connect I have a listener but I get two or n times the same message

  16. Morteza says:

    I’m using OpenHab and my topic (or my command) is like this: “/home/1/ard1/p1/com:command:on:1”. How can I convert this command here? Thanks.

  17. mohamed says:

    Hi,

    Haw i can receive messages when app is closed. when the application is closed by user the mqtt service is also destroyed beacause it run in the same process.
    I would like the mqtt service still running in background and bounded to a singleton mqtt android client in Application class. to continue receive message from mqtt broker in background and show notification to user to ropen application
    on click.

    thanks.

  18. rushabh says:

    Hey i dont have a username and password for HiveMq broker,so i wrote any random username and password and i published a topic(hello),now at reciever side i have mosquitto broker who is subscribed to same topic (hello),i am not able to recieve the topic,whats wrong?
    what is mqtthost?,i have put mqtthost as

    MQTTHOST=”tcp://broker.hivemq.com:1883″

    and topic as

    String topicstr=”hello/ro”;
    where i am going wrong?

    1. Hallo,

      glad to see you’re taking an interest in the MQTT protocol.
      When using our public broker (tcp://broker.hivemq.com:1883) there is no need for either username or password.

      Regards,
      Florian, from the HiveMQ Team.

  19. Krunal Bhavsar says:

    Thanks for good note on how to use mqtt in android. I tried the tutorial but stuck. As per section of connection, where it uses client.connect and then uses onSuccess, it does not put log in my console. Also when I try to publish and try it in my mobile, it throws nullpoint exception. When I tried to use client.isConnected(), I found that it is not connected.

    Could you possibly know why client.connect does not connect ? I tried tcp://broker.hivemq.com:1883 from MQTTlens and I was able to connect hence looks like no issue with firewall.

    Thanks,
    Krunal

  20. Hi,

    I am not getting onSuccess or onFailure message while using below code under onCreate. Could you please help ?

    ——————–
    String clientId = MqttClient.generateClientId();
    MqttAndroidClient client =
    new MqttAndroidClient(this.getApplicationContext(), “tcp://broker.hivemq.com:1883”,
    clientId);

    try {
    IMqttToken token = client.connect();
    token.setActionCallback(new IMqttActionListener() {
    @Override
    public void onSuccess(IMqttToken asyncActionToken) {
    // We are connected
    Log.d(TAG, “onSuccess”);
    }

    @Override
    public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
    // Something went wrong e.g. connection timeout or firewall problems
    Log.d(TAG, “onFailure”);

    }
    });
    } catch (MqttException e) {
    e.printStackTrace();
    }
    ——————–

    1. Raj Kumar Singh says:

      I had the sameissue, I fixed it by putting these lines inside Application tag in the manifest file.

      service android name= org.eclipse.paho.android.service.MqttService

      You might have kept it outside the applicatrion Tag

  21. Godfrey says:

    Hi Sandro, is there a way to provide the virtual host when connecting to a broker?
    My requirement is to connect to a vhost.

    My configuration example is:
    broker: tcp://my.broker.url:1883
    username: myuser
    password: myuser
    VHost: MyVHost

    I am able to successfully connect to the broker using the credentials (username, password) but i didnt get a way to provide the VHost.
    Please help.

  22. denisov says:

    NullPinterException when try to subscribe…. :-(

    1. Hi denisov,

      A NullPointerException is often a sign that something wasn’t initialized as expected. The best way to get help with that if you believe that is a Paho Bug would be to raise an issue with Paho or check if there is a known issue with a workaround available. The Paho Issue Tracker can be found here: https://github.com/eclipse/paho.mqtt.java/issues

      Hope this helps,
      Florian from the HiveMQ Team

  23. Claudio Calazans says:

    When I synch the gradle the only library that appears on my list is: org.eclipse.paho.android.service:1.0.3-SNAPSHOT.

    The org.eclipse.paho.client.MQTTv3.1.0.2, doesn’t.

    Can someone help me to understand if I missed something or if its an updated version?

    1. Hi Claudio,

      Did you use the correct maven repository ?

      Be aware that there are two different ones.
      One ends with …/paho-releases/
      the other one with …/paho-snapshots/

      Hope that helps,
      The HiveMQ Team

  24. Sarah says:

    How can I run hiveMQ locally to see published messages sent from ‘paho’ client

    1. Hi Sarah,

      Please see the installation guide for the HiveMQ broker.

      Kind regards,
      Florian from The HiveMQ Team.

  25. Sthor69 says:

    I tried with your code (with the 1.0.2 release of paho service) but I get a NullPointerException in the publish method.
    In particular, in MqttAndroidClient.java, at line 812 where there is the call to mqttService.publish(…), mqttService is null.

    What could be the reason?

    sthor69

  26. Tai says:

    Please help me.
    Read data at message from mqtt to listview on android studio.

  27. Lucas says:

    Extremely helpful, thanks!

  28. ashu says:

    hello

    im new to android development could someone please help me with below code. i want to make if statement from the mqtt payload . how can i make playload = connected then show it is Textview


    public void messageArrived(String topic, MqttMessage message) throws Exception {
    subText.setText(new String(message.getPayload()));
    // Vibrator.vibrate(500);
    }
    

  29. Aravindh Samidurai says:

    It’s working fine for me thank you developer but, i have some doubts about MQTT.
    1. What is message limit or daily quota in free account.
    2. How to create personal account.
    3. Is it possible to receive messages when app is background state.

    Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *