MQTT is a machine-to-machine /Internet of Things connectivity protocol. It’s designed to following use case.

  • Lightweight publish-subscribe-based messaging protocol for use on top of the TCP/IP protocol.
  • Connections to remote locations where a small code is required or the network bandwidth is limited.

MQTT Broker


The publish-subscribe messaging pattern requires a message broker. The broker is responsible for distributing messages to interested clients based on the topic of a message. It also holds the session of all persisted clients including subscriptions and missed messages.

There is a publically accessible sandbox server for the Eclipse IoT projects available at iot.eclipse.org:1883.

MQTT Client


Eclipse Paho project provides open-source client implementations of MQTT. Paho Android Service is an MQTT client library written in Java for developing applications on Android. 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. The Paho Android Service is an interface to the Paho Java MQTT Client library for the Android Platform.

Installation

Download  Paho Android Service and Android MQTT Client library. Go to your libs folder inside app folder and paste all your .jar To add the Paho Android Service as a dependency to your app add the following parts to your gradle file.

dependencies {
    compile files('libs/org.eclipse.paho.android.service-1.1.1.jar')
    compile files('libs/org.eclipse.paho.client.mqttv3-1.1.1.jar')
}

Permission


The Paho Android Service needs the following permissions to work.

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

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

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

MQTT Connection Option


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

private MqttConnectOptions getMqttConnectionOption() {
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setCleanSession(false);
        mqttConnectOptions.setAutomaticReconnect(true);
        mqttConnectOptions.setWill(Constants.PUBLISH_TOPIC, "I am going offline".getBytes(), 1, true);
        //mqttConnectOptions.setUserName("username");
        //mqttConnectOptions.setPassword("password".toCharArray());
        return mqttConnectOptions;
}

Clean session

On connection, a client sets the “clean session” flag. If the clean session is set to false, means when the client disconnects, any subscriptions it has will remain and any subsequent QoS 1 or 2 messages will be stored until it connects again in the future. If the clean session is true, then all subscriptions will be removed from the client when it disconnects.

Automatic Reconnect

Sets whether the client will automatically attempt to reconnect to the server if the connection is lost. It will initially wait 1 second before it attempts to reconnect, for every failed to reconnect attempt, the delay will double until it is at 2 minutes at which point the delay will stay at 2 minutes.

Wills

When a client connects to a broker, it may inform the broker that it has a will. This is a message that it wishes the broker to send when the client disconnects unexpectedly. The will message has a topic, QoS, and retains status just the same as any other message.

Receive MQTT Message


...
pahoMqttClient = new PahoMqttClient();
mqttAndroidClient = pahoMqttClient.getMqttClient(
getApplicationContext(), Constants.MQTT_BROKER_URL, Constants.CLIENT_ID);
      mqttAndroidClient.setCallback(new MqttCallbackExtended() {
      @Override
      public void connectComplete(boolean b, String s) {
       }
       @Override
       public void connectionLost(Throwable throwable) {
       }
       @Override
       public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
              setMessageNotification(s, new String(mqttMessage.getPayload()));
       }
       @Override
       public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
       }
});
....

Disconnect Options


Messages are published to the topic if the connection is available, but if it disconnects and connects again offline messages send. Holds the set of options that govern the behavior of Offline (or Disconnected) buffering of messages.

private DisconnectedBufferOptions getDisconnectedBufferOptions() {
        DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions();
        disconnectedBufferOptions.setBufferEnabled(true);
        disconnectedBufferOptions.setBufferSize(100);
        disconnectedBufferOptions.setPersistBuffer(true);
        disconnectedBufferOptions.setDeleteOldestMessages(false);
        return disconnectedBufferOptions;
}

Create MQTT Client


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

public MqttAndroidClient getMqttClient(Context context, String brokerUrl, String clientId) {
        mqttAndroidClient = new MqttAndroidClient(context, brokerUrl, clientId);
        try {
            IMqttToken token = mqttAndroidClient.connect(getMqttConnectionOption());
            token.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    mqttAndroidClient.setBufferOpts(getDisconnectedBufferOptions());
                    Log.d(TAG, "Success");
                }
                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.d(TAG, "Failure " + exception.toString());
                }
            });
        } catch (MqttException e) {
            e.printStackTrace();
        }
        return mqttAndroidClient;
    }

Publish Message

The MqttAndroidClient allows messages to be published via its publish method.

public void publishMessage(@NonNull MqttAndroidClient client,
            @NonNull String msg, int qos, @NonNull String topic)
            throws MqttException, UnsupportedEncodingException {
     byte[] encodedPayload = new byte[0];
     encodedPayload = msg.getBytes("UTF-8");
     MqttMessage message = new MqttMessage(encodedPayload);
     message.setId(5866);
     message.setRetained(true);
     message.setQos(qos);
     client.publish(topic, message);
}

Subscribe

Subscriptions can be created via the MqttAndroidClient.subscribe method, which takes the topic and the QOS as parameters and returns a IMqttToken.

public void subscribe(@NonNull MqttAndroidClient client,
            @NonNull final String topic, int qos) throws MqttException {
     IMqttToken token = client.subscribe(topic, qos);
     token.setActionCallback(new IMqttActionListener() {
     @Override
     public void onSuccess(IMqttToken iMqttToken) {
            Log.d(TAG, "Subscribe Successfully " + topic);
      }
      @Override
      public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
             Log.e(TAG, "Subscribe Failed " + topic);
      }
  });
}

Unsubscribe

public void unSubscribe(@NonNull MqttAndroidClient client,
            @NonNull final String topic) throws MqttException {
        IMqttToken token = client.unsubscribe(topic);
        token.setActionCallback(new IMqttActionListener() {
            @Override
            public void onSuccess(IMqttToken iMqttToken) {
                Log.d(TAG, "UnSubscribe Successfully " + topic);
            }
            @Override
            public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
                Log.e(TAG, "UnSubscribe Failed " + topic);
            }
        });
    }

Disconnect MQTT Client

public void disconnect(@NonNull MqttAndroidClient client)
                      throws MqttException {
        IMqttToken mqttToken = client.disconnect();
        mqttToken.setActionCallback(new IMqttActionListener() {
        @Override
        public void onSuccess(IMqttToken iMqttToken) {
                Log.d(TAG, "Successfully disconnected");
        }
        @Override
        public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
                Log.d(TAG, "Failed to disconnected " + throwable.toString());
        }
     });
 }

Download this project from GitHub

MQTTBox

MQTTBox enables you to create MQTT clients to publish or subscript topics, create MQTT virtual device networks, load test MQTT devices or brokers.

1.Create MQTT client

Create MQTT client

2.Config MQTT client

Host : iot.eclipse.org:1883 Protocol : mqtt/tcp

Config MQTT client

3.Publish/Subscribe

Publish/Subscribe

Related Post

Bluetooth Low Energy

Android NDK

Creating and Monitoring Geofences