Difference between revisions of "MQTT: Android Client Simple"

From OnnoWiki
Jump to navigation Jump to search
(Created page with "Android and MQTT: A Simple Guide How to develop an MQTT Client with Android Simplicity is the keynote of all true elegance MQTT stands for Message Queuing Telemetry Transport...")
 
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
Android and MQTT: A Simple Guide
+
'''PROBLEM:''' class startMqtt();
How to develop an MQTT Client with Android
 
Simplicity is the keynote of all true elegance
 
MQTT stands for Message Queuing Telemetry Transport and it is a powerful messaging transport protocol mostly used in Machine to Machine (M2M) and Internet of Things (IoT) communication contexts.
 
MQTT is preferred in these contexts, because it’s easy to implement and it’s a perfect fit for devices with limited resources.
 
  
But, why not taking advantage of these pros and using it also in smartphones?
 
In this article, we’ll develop an Android mobile application that uses MQTT protocol.
 
  
Why MQTT for your project?
+
==settings.gradle==
The rival of MQTT is the old, but gold, HTTP protocol.
 
But, why should you choose MQTT protocol for your project instead?
 
Below, a brief comparison table to better clarify the main aspects:
 
  
To sum up, MQTT is simpler, smaller and more secure compared to HTTP.
+
pluginManagement {
In the next section, we’ll analyze in depth the key concepts listed in the above table.
+
    repositories {
MQTT in a nutshell
+
        gradlePluginPortal()
MQTT is a publish-subscribe client-server messaging transport protocol.
+
        google()
Let’s be clear about what we mean for publish-subscribe and client-server architectures.
+
        mavenCentral()
Publish-Subscribe
+
        maven {
In publish/subscribe architecture, senders (publishers) don’t transmit messages directly to specific receivers (subscribers), but instead classify published messages into “categories” (called topics) without knowledge of which subscribers there may be.
+
            url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
 +
        }
 +
    }
 +
}
 +
dependencyResolutionManagement {
 +
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
 +
    repositories {
 +
        google()
 +
        mavenCentral()
 +
        maven {
 +
            url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
 +
        }
 +
    }
 +
}
 +
rootProject.name = "ITTSMQTTWildan"
 +
include ':app'
  
Publishers and subscribers never contact each other directly. The connection between them is handled by a third component called broker.
 
A practical example of publish/subscribe pattern in real life could be the newspaper: journalists (publishers) write several articles in the newspaper (broker) but they don’t know how many and which readers (subscribers) will read that article.
 
Client-Server
 
In Client-Server architecture, a client connects to a server for the use of a service.
 
In MQTT context, an MQTT client is a device that connects to an MQTT broker over a network. The service provided by the MQTT broker (server) is the possibility to publish and/or subscribe on one or many topics.
 
In MQTT, a client can be a publisher and subscriber or both.
 
  
Let’s start to communicate: Connection
 
Before starting the message exchange over topics, the client needs to initiate the communication by sending the CONNECT message to the broker.
 
With this message, a client presents itself to a broker providing the following main information:
 
ClientID
 
ClientID is an unique ID used by brokers to identify the client and store information (called session) about it.
 
An empty ClientID means an “anonymous” connection: therefore, the broker does not memorize any information about the client.
 
CleanSession
 
If the CleanSession is set to false and the broker has information stored for that client, broker uses the existing session and delivers previously queued messages to the client.
 
Instead, if the flag is set to true, it means discarding all existing sessions and messages for that client (mandatory if the ClientId is empty).
 
KeepAlive
 
This interval, express in seconds, defines the maximum period of time that broker and client can remain in contact without sending a message. The client needs to send regular PING messages, within the KeepAlive period, to the broker to maintain the connection alive.
 
Username and Password (optional)
 
Client can send a username and password to improve communication security.
 
WillMessage (optional)
 
A client can specify its last will message in the form of a MQTT message and topic. Broker will send this message, on behalf of the client, when the client “badly” disconnects.
 
Topic
 
As mentioned before, MQTT broker uses topic to decide which subscriber receives which message.
 
A client doesn’t create a topic before using it. A server accepts each valid topic without any initialization.
 
Topic is a string with the following characteristics:
 
At least 1 character in length
 
Case-sensitive
 
Composed by one or more levels separated by “/”
 
Let’s make an example!
 
Suppose you have temperature sensors scattered around your house. These sensors communicate with the thermostat using MQTT and the thermostat uses this information to regulate the home heating system.
 
  
Each sensor (publisher) communicates its temperature by publishing on a specific MQTT topic and thermostat (subscriber) monitors temperatures by checking these topics; below an example of the topics structure:
+
==build.gradle (app)==
myhome/groundfloor/kitchen
 
myhome/groundfloor/dining
 
myhome/groundfloor/livingroom
 
myhome/groundfloor/bedroom1
 
myhome/groundfloor/bedroom2
 
myhome/groundfloor/bathroom
 
Publish
 
A client writes data on a topic using the PUBLISH message.
 
This message contains the following information:
 
Topic Name
 
Payload: content of the message. MQTT protocol is data-agnostic. Payload is simply an alphanumeric string that needs to be interpreted by clients.
 
QoS level: indicates the Quality of Service Level (0, 1, 2). We’ll discuss it later.
 
Retain flag: defines if the message has to be saved by the broker as the last known good value for the topic. When a new client will subscribe to this topic, it receives the last retained message.
 
Below an example of the kitchen sensor publishing its reading temperature on kitchen topic:
 
Topic name: myhome/groundfloor/kitchen
 
Payload: 21.5
 
QoS level: 1
 
Retain flag: false
 
The temperature, inside the payload, is expressed in celsius degree (°C) with decimal point number. The subscriber (thermostat) needs to know this representation in order to correctly interpreter the temperature data.
 
Subscribe
 
To receive messages on topics, client sends a SUBSCRIBE message to the broker.
 
This message contains a list of subscriptions composed by:
 
Topic name
 
QoS level
 
Below an example of the thermostat subscribing on all sensor topics.
 
Topic name: myhome/groundfloor/kitchen
 
QoS level: 1
 
Topic name: myhome/groundfloor/dining
 
QoS level: 1
 
...
 
Topic name: myhome/groundfloor/bathroom
 
QoS level: 1
 
Unsubscribe
 
To delete existing subscriptions to a topic, client sends a UNSUBSCRIBE message to the broker.
 
Content is the same as the SUBSCRIBE message: a list of subscriptions.
 
QoS: Quality Of Service
 
QoS level is an agreement between sender and receiver on the guarantee of delivering a message.
 
But why is it so important? It improves reliability.
 
MQTT protocol manages the message retransmission and guarantees delivery, making communication in unreliable networks a bit less complex.
 
There are 3 levels:
 
0 — At most once
 
No guarantee of delivery. This level is called “fire and forget”.
 
Use it when you have a stable communication channel and when the loss of messages is acceptable.
 
1 — At least once
 
Guarantees that a message is delivered at least one time to the receiver.
 
Use it when clients can tolerate duplicate messages. It’s the most used.
 
2 — Exactly once
 
Guarantees that message is received only once by the receiver.
 
Use it when your application is critical and you cannot tolerate loss and duplicate messages.
 
By raising the QoS level, you will increase the reliability of the communication, but you will decrease the performance.
 
Android: Let’s get your hands dirty
 
Dealing with MQTT protocol on Android is quite easy.
 
MQTT works on TCP/IP stack, this means that the only requirement of the mobile device is the capability to connect to the internet.
 
  
There are only few Android libraries which implements MQTT protocol, but fortunately they are well documented and work fine.
 
The most famous libraries are:
 
Eclipse Paho Android Service
 
HiveMQ MQTT Client library
 
I have choosen the Eclipse Paho library, because it’s the most used one and it’s implemented in different programming languages and platforms.
 
  
Here, instructions on how to import Paho library in Android Studio.
+
....
Let’s coding!
+
dependencies {
The sample/simple MQTT Android app
+
    .....
To better understand how to use the MQTT Paho Library, I have developed a simple Android mobile application in Kotlin language.
+
    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
App is composed by two fragments:
+
    implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
Connect fragment
+
}
It allows you to insert the MQTT Broker details you want to connect to.
 
  
Client fragment
 
In this page, you can interact with the MQTT Broker by publishing and subscribing on the topics.
 
  
Let’s start: Connect to MQTT Broker
+
==main_activity.xml==
First of all, you need a MQTT Broker.
 
There are several websites offering free and/or enterprise MQTT broker service. Below, a list:
 
HiveMQ
 
Mosquitto
 
CloudMqtt
 
Adafruit IO
 
For demonstration purposes, I will use the free HiveMQ Public MQTT Broker. But, in general, I suggest Adafruit IO, because it provides several cool dashboards and more other functionalities.
 
Let’s take a look in depth at the Connect fragment.
 
This page allows inserting MQTT Broker connection details.
 
In the example below, we fill in the Server URI, but we left other fields empty because we’re using a public server that doesn’t need this information.
 
  
But, what happens behind the UI?
+
<?xml version="1.0" encoding="utf-8"?>
By opening this page, you do instantiate the MQTT Android client.
+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
MQTTClient is a wrapper of the Paho Library that implements the main functionalities of MQTT transport protocol.
+
    xmlns:app="http://schemas.android.com/apk/res-auto"
Below, class declaration and its main functions.
+
    xmlns:tools="http://schemas.android.com/tools"
 +
    android:layout_width="match_parent"
 +
    android:layout_height="match_parent"
 +
    tools:context=".MainActivity">
 +
 +
    <TextView
 +
        android:id="@+id/dataReceived"
 +
        android:layout_width="wrap_content"
 +
        android:layout_height="wrap_content"
 +
        app:layout_constraintBottom_toBottomOf="parent"
 +
        app:layout_constraintLeft_toLeftOf="parent"
 +
        app:layout_constraintRight_toRightOf="parent"
 +
        app:layout_constraintTop_toTopOf="parent" />
 +
 +
</androidx.constraintlayout.widget.ConstraintLayout>
  
By pressing the “CONNECT” button, you start the MQTT Broker connection procedure:
 
  
Let’s talk with the broker: Publish
 
If MQTT broker connection succeeds, you will be redirected to the Client fragment.
 
  
By filling in the “Topic” and “Message” fields and pressing the “PUBLISH” button, you send the desired message on the selected topic.
+
==Package helpers==
Below, the code snippet of publish() function:
 
  
Broker, tell me something: Subscribe and unsubscribe
+
package itts.onno.ittsmqttwildan.helpers;
If you want to receive messages from the broker, you have to subscribe to a topic.
+
To do that, fill the “Topic” field with the topic name and press the “SUBSCRIBE” button.
+
import android.content.Context;
 +
import android.util.Log;
 +
 +
import org.eclipse.paho.android.service.MqttAndroidClient;
 +
import org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions;
 +
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.MqttCallbackExtended;
 +
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
 +
import org.eclipse.paho.client.mqttv3.MqttException;
 +
import org.eclipse.paho.client.mqttv3.MqttMessage;
 +
 +
public class MqttHelper {
 +
    public MqttAndroidClient mqttAndroidClient;
 +
 +
    final String serverUri = "tcp://192.168.0.111:1883";
 +
 +
    final String clientId = "ExampleAndroidClient";
 +
    final String subscriptionTopic = "event";
 +
 +
    final String username = "test";
 +
    final String password = "123456";
 +
 +
    public MqttHelper(Context context) {
 +
        mqttAndroidClient = new MqttAndroidClient(context, serverUri, clientId);
 +
        mqttAndroidClient.setCallback(new MqttCallbackExtended() {
 +
            @Override
 +
            public void connectComplete(boolean b, String s) {
 +
                Log.w("mqtt", s);
 +
            }
 +
 +
            @Override
 +
            public void connectionLost(Throwable throwable) {
 +
            }
 +
 +
            @Override
 +
            public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
 +
                Log.w("Mqtt", mqttMessage.toString());
 +
            }
 +
 +
            @Override
 +
            public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
 +
            }
 +
        });
 +
        connect();
 +
    }
 +
 +
    public void setCallback(MqttCallbackExtended callback) {
 +
        mqttAndroidClient.setCallback(callback);
 +
    }
 +
 +
    private void connect(){
 +
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
 +
        mqttConnectOptions.setAutomaticReconnect(true);
 +
        mqttConnectOptions.setCleanSession(false);
 +
        mqttConnectOptions.setUserName(username);
 +
        mqttConnectOptions.setPassword(password.toCharArray()); 
 +
 +
        try {
 +
 +
            mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
 +
                @Override
 +
                public void onSuccess(IMqttToken asyncActionToken) {
 +
 +
                    DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions();
 +
                    disconnectedBufferOptions.setBufferEnabled(true);
 +
                    disconnectedBufferOptions.setBufferSize(100);
 +
                    disconnectedBufferOptions.setPersistBuffer(false);
 +
                    disconnectedBufferOptions.setDeleteOldestMessages(false);
 +
                    mqttAndroidClient.setBufferOpts(disconnectedBufferOptions);
 +
                    subscribeToTopic();
 +
                }
 +
 +
                @Override
 +
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
 +
                    Log.w("Mqtt", "Failed to connect to: " + serverUri + exception.toString());
 +
                }
 +
            });
 +
 +
        } catch (MqttException ex){
 +
            ex.printStackTrace();
 +
        }
 +
    }
 +
 +
    private void subscribeToTopic() {
 +
        try {
 +
            mqttAndroidClient.subscribe(subscriptionTopic, 0, null, new IMqttActionListener() {
 +
                @Override
 +
                public void onSuccess(IMqttToken asyncActionToken) {
 +
                    Log.w("Mqtt","Subscribed!");
 +
                }
 +
 
 +
                @Override
 +
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
 +
                    Log.w("Mqtt", "Subscribed fail!");
 +
                }
 +
            });
 +
 +
        } catch (MqttException ex) {
 +
            System.err.println("Exception whilst subscribing");
 +
            ex.printStackTrace();
 +
        }
 +
    }
 +
 +
 +
}
  
Here’s what happens when you click this button:
 
  
When a message is published in the subscribed topic, you will be notified with a “Toast” message. Below, an example:
 
  
To stop receiving messages from a specific topic, fill in the “Topic” field with the topic name and press the “UNSUBSCRIBE” button.
+
==MainActivity.java==
Below, the unsubscribe() function:
 
  
Time to say bye-bye: Disconnection
 
To properly terminate communication with the broker, you must send the disconnect message by pressing the “DISCONNECT” button.
 
Below, the disconnect() function:
 
  
Conclusion
+
package itts.onno.ittsmqttwildan;
And, that’s all!
+
Have you seen how easy it is to work with MQTT?
+
import androidx.appcompat.app.AppCompatActivity;
Next time, think twice before using HTTP/REST for server communication.
+
If the data you need to send is not too complex and you want a lightweight and easy protocol to implement, use MQTT.
+
import android.os.Bundle;
Here, you can find the project of the Android Mobile Application described in this article!
+
import android.util.Log;
 +
import android.widget.TextView;
 +
 +
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
 +
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
 +
import org.eclipse.paho.client.mqttv3.MqttMessage;
 +
 +
import itts.onno.ittsmqttwildan.helpers.MqttHelper;
 +
 +
public class MainActivity extends AppCompatActivity {
 +
 +
    MqttHelper mqttHelper;
 +
    TextView dataReceived;
 +
 +
    @Override
 +
    protected void onCreate(Bundle savedInstanceState) {
 +
        super.onCreate(savedInstanceState);
 +
        setContentView(R.layout.activity_main);
 +
 +
        dataReceived = (TextView) findViewById(R.id.dataReceived);
 +
 +
        // ------- problem & crashing-------------
 +
        // startMqtt();
 +
    }
 +
 +
    private void startMqtt(){
 +
        mqttHelper = new MqttHelper(getApplicationContext());
 +
        mqttHelper.setCallback(new MqttCallbackExtended() {
 +
            @Override
 +
            public void connectComplete(boolean b, String s) {
 +
 
 +
            }
 +
 +
            @Override
 +
            public void connectionLost(Throwable throwable) {
 +
 +
            }
 +
 +
            @Override
 +
            public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
 +
                Log.w("Debug",mqttMessage.toString());
 +
                dataReceived.setText(mqttMessage.toString());
 +
            }
 +
 +
            @Override
 +
            public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
 +
 +
            }
 +
          });
 +
    }
 +
 
 +
 +
}
 +
 
  
References
 
If you want to learn more about MQTT, I recommend the HiveMQ MQTT Essentials guide.
 
  
  
Line 179: Line 245:
 
==Referensi==
 
==Referensi==
  
 +
* https://github.com/wildan2711/mqtt-android-tutorial
 +
* https://wildanmsyah.wordpress.com/2017/05/11/mqtt-android-client-tutorial/
 +
* https://github.com/wildan2711/mqtt-android-tutorial
 
* https://medium.com/swlh/android-and-mqtt-a-simple-guide-cb0cbba1931c
 
* https://medium.com/swlh/android-and-mqtt-a-simple-guide-cb0cbba1931c
 
* https://www.eclipse.org/paho/index.php?page=clients/android/index.php
 
* https://www.eclipse.org/paho/index.php?page=clients/android/index.php

Latest revision as of 09:53, 9 April 2022

PROBLEM: class startMqtt();


settings.gradle

pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
        maven {
            url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
        }
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven {
            url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
        }
    }
}
rootProject.name = "ITTSMQTTWildan"
include ':app'


build.gradle (app)

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


main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/dataReceived"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>


Package helpers

package itts.onno.ittsmqttwildan.helpers;

import android.content.Context;
import android.util.Log;

import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions;
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.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;

public class MqttHelper {
    public MqttAndroidClient mqttAndroidClient;

    final String serverUri = "tcp://192.168.0.111:1883";

    final String clientId = "ExampleAndroidClient";
    final String subscriptionTopic = "event";

    final String username = "test";
    final String password = "123456";

    public MqttHelper(Context context) {
        mqttAndroidClient = new MqttAndroidClient(context, serverUri, clientId);
        mqttAndroidClient.setCallback(new MqttCallbackExtended() {
            @Override
            public void connectComplete(boolean b, String s) {
                Log.w("mqtt", s);
            }

            @Override
            public void connectionLost(Throwable throwable) { 
            }

            @Override
            public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
                Log.w("Mqtt", mqttMessage.toString());
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
            }
        });
        connect();
    }

    public void setCallback(MqttCallbackExtended callback) {
        mqttAndroidClient.setCallback(callback);
    }

    private void connect(){
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setAutomaticReconnect(true);
        mqttConnectOptions.setCleanSession(false);
        mqttConnectOptions.setUserName(username);
        mqttConnectOptions.setPassword(password.toCharArray());  

        try {

            mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {

                    DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions();
                    disconnectedBufferOptions.setBufferEnabled(true);
                    disconnectedBufferOptions.setBufferSize(100);
                    disconnectedBufferOptions.setPersistBuffer(false);
                    disconnectedBufferOptions.setDeleteOldestMessages(false);
                    mqttAndroidClient.setBufferOpts(disconnectedBufferOptions);
                    subscribeToTopic();
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.w("Mqtt", "Failed to connect to: " + serverUri + exception.toString());
                }
            });

        } catch (MqttException ex){
            ex.printStackTrace();
        }
    }

    private void subscribeToTopic() {
        try {
            mqttAndroidClient.subscribe(subscriptionTopic, 0, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Log.w("Mqtt","Subscribed!");
                }
 
                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.w("Mqtt", "Subscribed fail!");
                }
            });

        } catch (MqttException ex) {
            System.err.println("Exception whilst subscribing");
            ex.printStackTrace();
        }
    }


}


MainActivity.java

package itts.onno.ittsmqttwildan;

import androidx.appcompat.app.AppCompatActivity; 

import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttMessage;

import itts.onno.ittsmqttwildan.helpers.MqttHelper;

public class MainActivity extends AppCompatActivity {

    MqttHelper mqttHelper;
    TextView dataReceived;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); 

        dataReceived = (TextView) findViewById(R.id.dataReceived);

        // ------- problem & crashing-------------
        // startMqtt();
    }

    private void startMqtt(){
        mqttHelper = new MqttHelper(getApplicationContext());
        mqttHelper.setCallback(new MqttCallbackExtended() {
            @Override
            public void connectComplete(boolean b, String s) {
 
            }

            @Override
            public void connectionLost(Throwable throwable) {

            }

            @Override
            public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
                Log.w("Debug",mqttMessage.toString());
                dataReceived.setText(mqttMessage.toString());
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {

            }
         });
   }


}



Referensi