Android安卓使用mqtt推送消息,实现mqtt客户端

Android安卓使用mqtt推送消息,实现mqtt客户端

本文连接:https://www.cnblogs.com/muphy/p/14702211.html

 

先看效果

手机使用需要横屏

 

使用docker安装emqtt搭建mqtt服务

docker run --name emq -p 18083:18083 -p 1883:1883 -p 8084:8084 -p 8883:8883 -p 8083:8083 -d registry.cn-hangzhou.aliyuncs.com/synbop/emqttd:2.3.6

使用浏览器连接mqtt服务

http://192.168.2.100:18083/#/websocket    admin public

 

 

也可以使用MQTTX客户端连接mqtt服务器

配置连接信息

 

操作界面

 

 使用当前app连接,显示的都是默认值

 

代码

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="me.muphy.android.mqtt.demo">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission
        android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Androidmqttdemo">

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

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

 

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

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="188dp"
        android:layout_height="0dp"
        android:layout_marginTop="49dp"
        android:layout_marginBottom="54dp"
        android:contentDescription="@string/icon"
        app:layout_constraintBottom_toTopOf="@+id/editTextTextPersonName"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/touxiang" />

    <EditText
        android:id="@+id/editTextTextPersonName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="33dp"
        android:autofillHints=""
        android:ems="10"
        android:hint="@string/username_hint"
        android:inputType="textPersonName"
        app:layout_constraintBottom_toTopOf="@+id/editTextTextPassword"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

    <EditText
        android:id="@+id/editTextTextPassword"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="33dp"
        android:autofillHints=""
        android:ems="10"
        android:hint="@string/password_hint"
        android:inputType="textPassword"
        app:layout_constraintBottom_toTopOf="@+id/button"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editTextTextPersonName" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="61dp"
        android:layout_marginBottom="28dp"
        android:text="@string/button_login"
        app:layout_constraintBottom_toTopOf="@+id/textView2"
        app:layout_constraintStart_toStartOf="@+id/editTextTextPassword"
        app:layout_constraintTop_toBottomOf="@+id/editTextTextPassword" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="12dp"
        android:layout_marginBottom="27dp"
        android:text="@string/app_version"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="@+id/button"
        app:layout_constraintTop_toBottomOf="@+id/button" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.32" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.61" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.71" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.9" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.38" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.12" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.43" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline9"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.32" />

    <EditText
        android:id="@+id/pubTopic"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="topic"
        android:inputType="textPersonName"
        app:layout_constraintBottom_toTopOf="@+id/guideline4"
        app:layout_constraintEnd_toStartOf="@+id/guideline2"
        app:layout_constraintStart_toStartOf="@+id/guideline3"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="发布"
        android:textSize="24sp"
        app:layout_constraintBottom_toTopOf="@+id/guideline4"
        app:layout_constraintEnd_toStartOf="@+id/guideline3"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/pubBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="确认"
        app:layout_constraintBottom_toTopOf="@+id/guideline4"
        app:layout_constraintEnd_toStartOf="@+id/guideline5"
        app:layout_constraintStart_toStartOf="@+id/guideline2"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="订阅"
        android:textSize="24sp"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintEnd_toStartOf="@+id/guideline3"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="@+id/guideline9" />

    <EditText
        android:id="@+id/subTopic"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="topic"
        android:inputType="textPersonName"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintEnd_toStartOf="@+id/guideline2"
        app:layout_constraintStart_toStartOf="@+id/guideline3"
        app:layout_constraintTop_toTopOf="@+id/guideline9" />

    <Button
        android:id="@+id/subBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="确认"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintEnd_toStartOf="@+id/guideline5"
        app:layout_constraintStart_toStartOf="@+id/guideline2"
        app:layout_constraintTop_toTopOf="@+id/guideline9" />

    <EditText
        android:id="@+id/subText"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:editable="false"
        android:ems="10"
        android:gravity="start|top"
        android:inputType="textMultiLine"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="@+id/guideline6"
        app:layout_constraintVertical_bias="0.493" />

    <EditText
        android:id="@+id/pubText"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:ems="10"
        android:gravity="start|top"
        android:inputType="textMultiLine"
        app:layout_constraintBottom_toTopOf="@+id/guideline9"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="@+id/guideline4" />
</androidx.constraintlayout.widget.ConstraintLayout>
View Code

 

MainActivity.java

 

package me.muphy.android.mqtt.demo;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

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

public class MainActivity extends AppCompatActivity {

    private static String TAG = MainActivity.class.getSimpleName();
    private static MqttAndroidClient mqttAndroidClient;
    private Button pubBtn;
    private Button subBtn;
    private Button connBtn;
    private EditText pubText;
    private EditText subText;
    private EditText pubContent;
    private EditText pubTopic;
    private EditText subTopic;
    private EditText subTopics;
    private TextView pubMsg;
    private TextView subMsg;
    private TextView status;
    private EditText passwordEt;
    private EditText usernameEt;
    private EditText clientIdEt;
    private EditText hostEt;

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

        pubBtn = findViewById(R.id.pubBtn);
        subBtn = findViewById(R.id.subBtn);
        connBtn = findViewById(R.id.connBtn);
        pubText = findViewById(R.id.pubText);
        pubContent = findViewById(R.id.pubContent);
        subText = findViewById(R.id.subText);
        pubTopic = findViewById(R.id.pubTopic);
        subTopic = findViewById(R.id.subTopic);
        subTopics = findViewById(R.id.subTopics);
        pubMsg = findViewById(R.id.pubMsg);
        subMsg = findViewById(R.id.subMsg);
        status = findViewById(R.id.status);
        passwordEt = findViewById(R.id.password);
        usernameEt = findViewById(R.id.username);
        clientIdEt = findViewById(R.id.clientId);
        hostEt = findViewById(R.id.host);

        connBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                connect();
            }
        });

        pubBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String topic = pubTopic.getText().toString();
                if (topic.isEmpty()) {
                    topic = "test";
                }
                String message = pubContent.getText().toString();
                if (message.isEmpty()) {
                    message = "hello world!";
                }
                publishMessage(topic, message);
            }
        });

        subBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String topic = subTopic.getText().toString();
                if (topic.isEmpty()) {
                    topic = "test";
                }
                subscribeTopic(topic);
            }
        });
    }

    /**
     * String host = "tcp://58.16.134.114:48989";
     * String clientId = "android_mqtt_client";
     * String userName = "admin";
     * String passWord = "mf@123";
     */
    public void connect() {
        String host = hostEt.getText().toString();
        String clientId = clientIdEt.getText().toString();
        String userName = usernameEt.getText().toString();
        String passWord = passwordEt.getText().toString();
        /* 获取MQTT连接信息clientId、username、password。 对接阿里云会用到 */
        /*//对接阿里云服务 才会用到
        final String PRODUCTKEY = "a11xsrW****";
        final String DEVICENAME = "paho_android";
        final String DEVICESECRET = "tLMT9QWD36U2SArglGqcHCDK9rK9****";
        AiotMqttOption aiotMqttOption = new AiotMqttOption().getMqttOption(PRODUCTKEY, DEVICENAME, DEVICESECRET);
        if (aiotMqttOption == null) {
            Log.e(TAG, "device info error");
        } else {
            clientId = aiotMqttOption.getClientId();
            userName = aiotMqttOption.getUsername();
            passWord = aiotMqttOption.getPassword();
        }*/
        if (clientId.isEmpty()) {
            clientId = "android_mqtt_client";
        }
        if (host.isEmpty()) {
            host = "tcp://127.0.0.1:1883";
        }

        /* 创建MqttConnectOptions对象,并配置username和password。 */
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        if (!userName.isEmpty()) {
            mqttConnectOptions.setUserName(userName);
        }
        if (!passWord.isEmpty()) {
            mqttConnectOptions.setPassword(passWord.toCharArray());
        }

        if (mqttAndroidClient != null) {
            try {
                mqttAndroidClient.disconnect(); //断开连接
            } catch (MqttException e) {
                e.printStackTrace();
            }
            mqttAndroidClient = null;
        }

        /* 创建MqttAndroidClient对象,并设置回调接口。 */
        mqttAndroidClient = new MqttAndroidClient(getApplicationContext(), host, clientId);
        String finalHost = host;
        mqttAndroidClient.setCallback(new MqttCallback() {
            @Override
            public void connectionLost(Throwable cause) {
                String msg = "";
                if (cause != null) {
                    msg = "," + cause.getMessage();
                }
                Log.i(TAG, "连接掉线>host:" + finalHost + msg);
                status.setText("未连接>host:" + finalHost + msg);
            }

            @Override
            public void messageArrived(String topic, MqttMessage message) throws Exception {
                Log.i(TAG, "topic: " + topic + ", msg: " + new String(message.getPayload()));
                subText.append("topic: " + topic + ", msg: " + new String(message.getPayload()) + "\n\n");
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {
                Log.i(TAG, "已发送");
            }
        });



        /* 建立MQTT连接。 */
        try {
            mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Log.i(TAG, "连接成功:" + finalHost);
                    status.setText("已连接:" + finalHost);
//                    subscribeTopic("test");
//                    subscribeTopic("/device_online_status");
//                    subscribeTopic("/read-property");
//                    subscribeTopic("/report-property");
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    String msg = "";
                    if (exception != null) {
                        msg = "," + exception.getMessage();
                    }
                    Log.i(TAG, "连接失败>host:" + finalHost + msg);
                    status.setText("未连接>host:" + finalHost + msg);
                    exception.printStackTrace();
                }
            });

        } catch (MqttException e) {
            Log.i(TAG, "连接失败:" + e.getMessage());
            status.setText("未连接:" + e.getMessage());
            e.printStackTrace();
        }
    }

    public void publishMessage(String topic, String payload) {
        try {
            if (mqttAndroidClient.isConnected() == false) {
                mqttAndroidClient.connect();
            }

            MqttMessage message = new MqttMessage();
            message.setPayload(payload.getBytes());
            message.setQos(0);
            mqttAndroidClient.publish(topic, message, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Log.i(TAG, "发布成功>topic:" + topic + ",payload:" + payload);
                    pubText.append("发布成功>topic:" + topic + ",payload:" + payload + "\n\n");
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.i(TAG, "发布失败>topic:" + topic + ",payload:" + payload);
                    String msg = "";
                    if (exception != null) {
                        msg = "," + exception.getMessage();
                        exception.printStackTrace();
                    } else {
                        msg = ",未知错误!";
                    }
                    pubMsg.setText(msg);
                    pubText.append("发布失败>topic:" + topic + ",payload:" + payload + "\n\n");
                }
            });
        } catch (MqttException e) {
            Log.i(TAG, "发布失败>topic:" + topic + ",payload:" + payload);
            String msg = "";
            if (e != null) {
                msg = "," + e.getMessage();
                e.printStackTrace();
            } else {
                msg = "未知错误!";
            }
            pubMsg.setText(msg);
            pubText.append("发布失败>topic:" + topic + ",payload:" + payload + "\n\n");
        }
    }

    public void subscribeTopic(String topic) {
        try {
            mqttAndroidClient.subscribe(topic, 0, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Log.i(TAG, "订阅成功>topic:" + topic);
                    subTopics.append(topic + "\n");
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.i(TAG, "订阅失败>topic:" + topic);
                    String msg = "";
                    if (exception != null) {
                        msg = "," + exception.getMessage();
                        exception.printStackTrace();
                    } else {
                        msg = "未知错误!";
                    }
                    pubMsg.setText(msg);
                }
            });

        } catch (MqttException e) {
            Log.i(TAG, "订阅失败>topic:" + topic);
            String msg = "";
            if (e != null) {
                msg = "," + e.getMessage();
                e.printStackTrace();
            } else {
                msg = "未知错误!";
            }
            pubMsg.setText(msg);
        }
    }

    @Override
    public void onDestroy() {
        if (mqttAndroidClient != null) {
            try {
                mqttAndroidClient.disconnect(); //断开连接
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
        super.onDestroy();
    }

}

 

 

 

参考:https://www.alibabacloud.com/help/zh/doc-detail/146630.htm

本文连接:https://www.cnblogs.com/muphy/p/14702211.html

 

posted @ 2021-04-25 21:39  明月心~  阅读(6900)  评论(0编辑  收藏  举报