MQTT: Android Studio MQTT Test Client

From OnnoWiki
Jump to navigation Jump to search

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 = "ITTS MQTT Test Client"
include ':app'


build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


build.gradle app

buildscript{
    repositories {
        // Add the Maven address.
        maven { url 'https://developer.huawei.com/repo/' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.0.3'
        classpath 'com.huawei.agconnect:agcp:1.5.2.300'
    }
}
plugins {
    id 'com.android.application'
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "itts.onno.ittsmqtttestclient"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0" 

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies { 
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
    implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
    implementation 'org.greenrobot:eventbus:3.3.1'
}


activity_main.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">

    <EditText
        android:id="@+id/mqttserver"
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="132dp"
        android:ems="10"
        android:hint="MQTT broker server name / IP address"
        android:inputType="text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.454"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/> 

    <EditText
        android:id="@+id/username"
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:ems="10"
        android:hint="MQTT username"
        android:inputType="text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.4"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/mqttserver"/> 

    <EditText
        android:id="@+id/password"
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:ems="10"
        android:hint="MQTT password"
        android:inputType="text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.4"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/username"/>

    <EditText
        android:id="@+id/mqttclientid"
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:ems="10"
        android:hint="MQTT client id"
        android:inputType="text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.4"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/password"/> 

    <Button
        android:id="@+id/btnProceed"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:text="Proceed"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/btnReset"
        app:layout_constraintHorizontal_bias="0.207"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.963"/> 

    <Button
        android:id="@+id/btnReset"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:text="Reset"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.963"/>

</androidx.constraintlayout.widget.ConstraintLayout>

activity_mqttmain.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=".MQTTMain">

    <Button
        android:id="@+id/btnConnect"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginTop="20dp"
        android:text="Connect"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_editor_absoluteX="0dp"/> 

    <EditText
        android:id="@+id/mqttsubstopic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:ems="10"
        android:hint="MQTT Subscribe Topic"
        android:inputType="text"
        app:layout_constraintTop_toBottomOf="@+id/btnConnect"
        tools:layout_editor_absoluteX="0dp"/>

    <Button
        android:id="@+id/btnSubscribe"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginTop="10dp"
        android:text="Subscribe"
        app:layout_constraintTop_toBottomOf="@id/mqttsubstopic"
        tools:layout_editor_absoluteX="0dp"/> 

    <EditText
        android:id="@+id/mqttpublishtext"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:ems="10"
        android:hint="MQTT Publish Text"
        android:inputType="text"
        app:layout_constraintTop_toBottomOf="@id/btnSubscribe"
        tools:layout_editor_absoluteX="0dp"/> 

    <Button
        android:id="@+id/btnPublish"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginTop="10dp"
        android:text="Publish"
        app:layout_constraintTop_toBottomOf="@id/mqttpublishtext"
        tools:layout_editor_absoluteX="0dp"/> 

    <TextView
        android:id="@+id/mqttreceivedmessage"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:layout_marginTop="10dp"
        android:hint="MQTT Message Received from Broker"
        app:layout_constraintTop_toBottomOf="@id/btnPublish"
        tools:layout_editor_absoluteX="0dp"/> 

    <Button
        android:id="@+id/btndisConnect"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginTop="20dp"
        android:text="Disconnect"
        app:layout_constraintTop_toBottomOf="@id/mqttreceivedmessage"
        tools:layout_editor_absoluteX="0dp"/> 

</androidx.constraintlayout.widget.ConstraintLayout>


MainActivity.java

package itts.onno.ittsmqtttestclient;

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

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

        Button btnProceed = (Button)findViewById(R.id.btnProceed);
        btnProceed.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                EditText mqttserver = (EditText) findViewById(R.id.mqttserver);
                String smqttserver = mqttserver.getText().toString() ;
                EditText mqttusername = (EditText) findViewById(R.id.username);
                String smqttusername = mqttusername.getText().toString() ;
                EditText mqttpassword = (EditText) findViewById(R.id.password);
                String smqttpassword = mqttpassword.getText().toString() ;
                EditText mqttclientid = (EditText) findViewById(R.id.mqttclientid);
                String smqttclientid = mqttclientid.getText().toString() ; 

                // String smqttserver = "percobaan testing";
                Intent i = new Intent(MainActivity.this, MQTTMain.class);
                i.putExtra("IDmqttserver", smqttserver);
                i.putExtra("IDmqttusername", smqttusername);
                i.putExtra("IDmqttpassword", smqttpassword);
                i.putExtra("IDmqttclientid", smqttclientid);
                startActivity(i);
            }
        }); 

        Button btnReset = (Button)findViewById(R.id.btnReset);
        btnReset.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EditText mqttserver = (EditText) findViewById(R.id.mqttserver);
                mqttserver.setText("");
                EditText mqttusername = (EditText) findViewById(R.id.username);
                mqttusername.setText("");
                EditText mqttpassword = (EditText) findViewById(R.id.password);
                mqttpassword.setText("");
                EditText mqttclientid = (EditText) findViewById(R.id.mqttclientid);
                mqttclientid.setText("");
            }
        });
    }
}


MQTTMain.java

package itts.onno.ittsmqtttestclient;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
import android.view.View;

import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
 

public class MQTTMain extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mqttmain); 

        String smqttusername = getIntent().getStringExtra( "IDmqttusername");
        String smqttpassword = getIntent().getStringExtra( "IDmqttpassword");
        String smqttclientid = getIntent().getStringExtra( "IDmqttclientid");
        String smqttserver = getIntent().getStringExtra( "IDmqttserver");

        // smqttserver = "tcp://"+smqttserver+":1883";
        // TextView textView = (TextView) findViewById(R.id.mqttreceivedmessage);
        // textView.setText( smqttserver); //set text for text view 

        findViewById(R.id.btnConnect).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        boolean b = MqttManager.getInstance().creatConnect( "tcp://"+smqttserver+":1883", smqttusername, smqttpassword, smqttclientid);
                    }
                }).start();
            }
        });

        findViewById(R.id.btnPublish).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() { 

                        EditText mqttsubstopic = (EditText) findViewById(R.id.mqttsubstopic);
                        String smqttsubstopic = mqttsubstopic.getText().toString() ;
                        EditText mqttpublishtext = (EditText) findViewById(R.id.mqttpublishtext);
                        String smqttpublishtext = mqttpublishtext.getText().toString() ; 

                        MqttManager.getInstance().publish( smqttsubstopic, 2, smqttpublishtext.getBytes());
                    }
                }).start();
            }
        });

        findViewById(R.id.btnSubscribe).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        EditText mqttsubstopic = (EditText) findViewById(R.id.mqttsubstopic);
                        String smqttsubstopic = mqttsubstopic.getText().toString() ; 

                        MqttManager.getInstance().subscribe( smqttsubstopic , 2);
                    }
                }).start();
            }
        });

        findViewById(R.id.btndisConnect).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            MqttManager.getInstance().disConnect();
                        } catch (MqttException e) {  
                        }
                    }
                }).start(); 
            }
        });
       EventBus.getDefault().register(this);
   }


    /**
     * Subscribe to received messages
     * The Event type here can be customized as needed, here is only a basic demonstration
     *
     * @param message
     */
    @Subscribe
    public void onEvent(MqttMessage message) {
        TextView textView = (TextView) findViewById(R.id.mqttreceivedmessage);
        textView.setText( message.toString() ); //set MQTT message as text
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    } 
}


MqttManager.java

package itts.onno.ittsmqtttestclient;

import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence;

public class MqttManager {

    // instance
    private static MqttManager mInstance = null;

    // Private instance variables
    private MqttClient client;
    private MqttConnectOptions conOpt;
    private boolean clean = true; 

    // callback
    private MqttCallbackBus mCallback;
    private MqttManager() {
        mCallback = new MqttCallbackBus();
    } 

    public static MqttManager getInstance() {
        if (null == mInstance) {
            mInstance = new MqttManager();
        }
        return mInstance;
    } 

    /**
     * Release the instance, and the resources it references
     */
    public static void release() {
        try {
            if (mInstance != null) {
                mInstance.disConnect();
                mInstance = null;
            }
        } catch (Exception e) {
        }
    } 

    /**
     * Create Mqtt connection
     *
     * @param brokerUrl (tcp://xxxxxx:1883)
     * @param userName
     * @param password
     * @param clientId  clientId
     * @return
     */
    public boolean creatConnect(String brokerUrl, String userName, String password, String clientId) {
        boolean flag = false;
        String tmpDir = System.getProperty("java.io.tmpdir");
        MqttDefaultFilePersistence dataStore = new MqttDefaultFilePersistence(tmpDir); 

        try {
            // Construct the connection options object that contains connection parameters
            // such as cleanSession and LWT
            conOpt = new MqttConnectOptions();
            conOpt.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
            conOpt.setCleanSession(clean);
            if (password != null) {
                conOpt.setPassword(password.toCharArray());
            }
            if (userName != null) {
                conOpt.setUserName(userName);
            } 

            // Construct an MQTT blocking mode client
            client = new MqttClient(brokerUrl, clientId, dataStore);  

            // Set this wrapper as the callback handler
            client.setCallback(mCallback);
            flag = doConnect();
        } catch (MqttException e) {
        }
        return flag;
    }

    /**
     * establish connection
     *
     * @return
     */
    public boolean doConnect() {
        boolean flag = false;
        if (client != null) {
            try {
                client.connect(conOpt);
                // Logger.d("Connected to " + client.getServerURI() + " with client ID " + client.getClientId());
                flag = true;
            } catch (Exception e) {
            }
        }
        return flag;
    }

    /**
     * Publish / send a message to an MQTT server
     *
     * @param topicName the name of the topic to publish to
     * @param qos       the quality of service to delivery the message at (0,1,2)
     * @param payload   the set of bytes to send to the MQTT server
     * @return boolean
     */
    public boolean publish(String topicName, int qos, byte[] payload) {

        boolean flag = false;

        if (client != null && client.isConnected()) {

            // Logger.d("Publishing to topic \"" + topicName + "\" qos " + qos); 

            // Create and configure a message
            MqttMessage message = new MqttMessage(payload);
            message.setQos(qos); 

            // Send the message to the server, control is not returned until
            // it has been delivered to the server meeting the specified
            // quality of service.
            try {
                client.publish(topicName, message);
                flag = true;
            } catch (MqttException e) {
            }
        }
        return flag;
    }

    /**
     * Subscribe to a topic on an MQTT server
     * Once subscribed this method waits for the messages to arrive from the server
     * that match the subscription. It continues listening for messages until the enter key is
     * pressed.
     *
     * @param topicName to subscribe to (can be wild carded)
     * @param qos       the maximum quality of service to receive messages at for this subscription
     * @return boolean
     */
    public boolean subscribe(String topicName, int qos) {

        boolean flag = false; 

        if (client != null && client.isConnected()) {
            // Subscribe to the requested topic
            // The QoS specified is the maximum level that messages will be sent to the client at.
            // For instance if QoS 1 is specified, any messages originally published at QoS 2 will
            // be downgraded to 1 when delivering to the client but messages published at 1 and 0
            // will be received at the same level they were published at. 

            // Logger.d("Subscribing to topic \"" + topicName + "\" qos " + qos);
            try {
                client.subscribe(topicName, qos);
                flag = true; 

            } catch (MqttException e) {
            }
        }
        return flag;
    }

    /**
     * disconnect the connection
     *
     * @throws MqttException
     */
    public void disConnect() throws MqttException {
        if (client != null && client.isConnected()) {
            client.disconnect();
        }
    }
}


MqttCallbackBus.java

package itts.onno.ittsmqtttestclient;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.greenrobot.eventbus.EventBus;

/**
 * Dispatching events using EventBus
 *
 * @author LichFaker on 16/3/25.
 * @Email lichfaker@gmail.com
 */
public class MqttCallbackBus implements MqttCallback {

    @Override
    public void connectionLost(Throwable cause) {
    }

    @Override
    public void messageArrived(String topic, MqttMessage message) {
        EventBus.getDefault().post(message);
    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
    }
}



Pranala Menarik