Paho Android Service - MQTT Client Library Encyclopedia
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.
Overview of Paho Android Service
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.
Pahao Android Service | |
---|---|
Language | Java |
License | Eclipse Public License v1.0 and Eclipse Distribution License v1.0 |
Website | eclipse.org/paho/clients/android/ |
API Style | Asynchronous |
MQTT Features Supported by the Paho Android Service
Feature | |
---|---|
MQTT 3.1 | Yes |
MQTT 3.1.1 | Yes |
LWT | Yes |
SSL/TLS | No |
Automatic Reconnect | No (On the road map) |
Advanced Features: Paho Android Service
Feature | |
---|---|
QoS 0 | Yes |
QoS 1 | Yes |
QoS 2 | Yes |
Authentication | Yes |
Throttling | No |
How to Use the Paho Android Service?
Installation of Paho Android Service
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 your 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 an 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 of Paho Android Service
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 this folder, which can be opened with Android Studio.
org.eclipse.paho.android.service/org.eclipse.paho.android.sample
Sandro Kock
Sandro Kock is a mobile developer at SSV Software Systems, responsible for developing mobile solutions, with a focus on IoT/M2M. The maintainer of mqtt-elements, a set of MQTT WebComponents, created with Polymer.