描述:最近在弄iot设备,碰到一个需求,app是c端,硬件设备嵌入式程序是d端,服务器负责通信,然后c端发送配网指令,d端收到指令,进入配网状态,然后遥控器发送红外指令,硬件传感器收到红外指令,然后d端发送消息到c端,c端接收指令,并响应。

遇到问题:我app的c端,收不到d端发给我的指令,我一直以为是框架有问题,因为网页端日志是可以看到硬件收发指令是正常的,找了很久,发现app必须首先订阅d端,然后才能收到d端的指令,不然收不到,这非常尴尬,然后我订阅了d端的指令,再次请求,成功了。

教训:一定要弄懂mqtt的机制原理,然后再去做逻辑交互,不然你就会浪费许多时间,一头雾水,原地转圈圈。

step1:

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.demoanalytic"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        ndk {
            abiFilters 'arm64-v8a'
        }

    }
    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 fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    //noinspection GradleCompatible
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.google.firebase:firebase-core:16.0.9'
    implementation project(':andmqtt')
    implementation 'com.blankj:utilcode:1.22.0'
    implementation("org.greenrobot:eventbus:3.3.1")
    implementation 'com.google.code.gson:gson:2.8.0'

}
apply plugin: 'com.google.gms.google-services'

step2: D:\project\push\Infrared\mqtt\one_fice\v7\kotlin\DemoAnalytic\app\src\main\AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.demoanalytic">

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />

    <uses-permission android:name="android.permission.FLASHLIGHT" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <!--ZXING END-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />


    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />

    <!--esp touch-->
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.CAMERA" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <!--对讲权限-->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.RECORD_VIDEO" />

    <!--检测网络状态权限-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.BLUETOOTH" />


    <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/AppTheme">
        <service android:name="com.example.demoanalytic.MQTTService" />

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

step3:

package com.example.demoanalytic

const val MQTT_SERVICE = "tcp://1.48.180"
const val MQTT_PORT = 180803
const val PLUG_TOPIC_REC = "/%s/%s/C1/"
const val SET_SWITCH = "WY+SWITCH=%s"
const val SET_IR_SMART = "WY+IR=match_start"

const val SET_IR_SMART_END = "WY+IR=match_end"
const val PLUG_TOPIC = "/%s/%s/D1/"

step4:

package com.example.demoanalytic

import android.content.Intent
import android.os.Build
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.blankj.utilcode.util.ServiceUtils
import kotlinx.android.synthetic.main.activity_main.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class MainActivity : AppCompatActivity() {
    private val productId = "zcz004"
    private val equipmentId = "zcz004100629"
    // https://github.com/Rairmmd/AndMqtt.git 参考网址,需要lib的自行去下载

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        EventBus.getDefault().register(this)
        EventBus.getDefault().postSticky(MqttMsg(true))
        if (ServiceUtils.isServiceRunning(MQTTService::class.java.name)) {
            ServiceUtils.stopService(MQTTService::class.java.name)
        }
        val intent = Intent(this@MainActivity, MQTTService::class.java)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            this@MainActivity.startForegroundService(intent)
        } else {
            startService(intent)
        }

        btn_pub_d.setOnClickListener {
            EventBus.getDefault().post(
                MqttBean(
                    String.format(
                        PLUG_TOPIC,
                        productId,
                        equipmentId
                    ), true
                )
            )
        }


        btn_open.setOnClickListener {
            EventBus.getDefault().post(
                MqttBean(
                    String.format(PLUG_TOPIC_REC, productId, equipmentId),
                    String.format(SET_SWITCH, "1")
                )
            )
        }

        btn_close.setOnClickListener {
            EventBus.getDefault().post(
                MqttBean(
                    String.format(PLUG_TOPIC_REC, productId, equipmentId),
                    String.format(SET_SWITCH, "0")
                )
            )
        }


        btn_smart_sure.setOnClickListener {


            /*
            * 连接肯定是正常的   我是不是没订阅d 端的数据  所以收不到呢  那么问题来了  应该怎么订阅呢
            * */



            EventBus.getDefault().post(
                MqttBean(
                    String.format(
                        PLUG_TOPIC_REC,
                        productId,
                        equipmentId
                    ), SET_IR_SMART
                )
            )
        }

        btn_smart_cancel.setOnClickListener {
            EventBus.getDefault().post(
                MqttBean(
                    String.format(
                        PLUG_TOPIC_REC,
                        productId,
                        equipmentId
                    ), SET_IR_SMART_END
                )
            )
            EventBus.getDefault().post(StopService(true))
            EventBus.getDefault().post(
                MqttBean(
                    String.format(
                        PLUG_TOPIC,
                        productId,
                        equipmentId
                    ), "", true
                )
            )
        }

    }

    override fun onDestroy() {
        try {
            Log.e("TAG", "onDestroy: " + ServiceUtils.stopService(MQTTService::class.java.name))
            Log.e(
                "TAG",
                "onDestroy: " + ServiceUtils.stopService("org.eclipse.paho.android.service.MqttService")
            )
        } catch (e: java.lang.Exception) {
            e.toString()
        }
        super.onDestroy()
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun showMsgDialog(showMsg: ShowMsg) {

    }
}

step5:

package com.example.demoanalytic;


        import java.io.Serializable;

public class MqttBean implements Serializable {
    public String topic;
    public String message;
    public boolean register;
    public boolean isUnregister;

    public MqttBean(String topic, String message, boolean isUnregister) {
        this.topic = topic;
        this.message = message;
        this.isUnregister = isUnregister;
    }

    public MqttBean(String topic, String message) {
        this.topic = topic;
        this.message = message;
    }

    public MqttBean(String topic, boolean register) {
        this.topic = topic;
        this.register = register;
    }


}

step6:

package com.example.demoanalytic;

import java.io.Serializable;

public class MqttMsg implements Serializable {
    public String topic;
    public String message;
    public float Pm25_Data;//0-500
    public float Temperature;//0-80
    public float CO2_Data;//0-2000
    public float TVOC_Data;//0-2
    public float HCHO_Data;//0-1
    public float Humidity;//0-100
    public int ModeState;//0关 1监测灯 2有氧灯光
    public int light;//1--6
    public int ScreenStatus;//0关屏 1开屏

    private int Pm25Level;
    private int TemperatureLevel;
    private int CO2Level;
    private int TVOCLevel;
    private int HCHOLevel;
    private int HumidityLevel;
    private int AllLevel;

    private String Pm25LevelText;
    private String TemperatureLevelText;
    private String CO2LevelText;
    private String TVOCLevelText;
    private String HCHOLevelText;
    private String HumidityLevelText;
    private String AllLevelText;
    private boolean isClosed;

    private String clock1;
    private String clock2;
    private String clock3;

    private boolean clock1On;
    private boolean clock2On;
    private boolean clock3On;

    public String plug;

    private static final String TAG = "MqttMsg";

    public String getClock1() {
        return clock1;
    }

    public void setClock1(String clock1) {
        this.clock1 = clock1;
    }

    public String getClock2() {
        return clock2;
    }

    public void setClock2(String clock2) {
        this.clock2 = clock2;
    }

    public String getClock3() {
        return clock3;
    }

    public void setClock3(String clock3) {
        this.clock3 = clock3;
    }

    public boolean isClock1On() {
        return clock1On;
    }

    public void setClock1On(boolean clock1On) {
        this.clock1On = clock1On;
    }

    public boolean isClock2On() {
        return clock2On;
    }

    public void setClock2On(boolean clock2On) {
        this.clock2On = clock2On;
    }

    public boolean isClock3On() {
        return clock3On;
    }

    public void setClock3On(boolean clock3On) {
        this.clock3On = clock3On;
    }

    public MqttMsg(boolean isClosed) {
        this.isClosed = isClosed;
    }

    public boolean isClosed() {
        return isClosed;
    }

    public void setClosed(boolean closed) {
        isClosed = closed;
    }

    public String equipmentId;
    public String productId;

    public MqttMsg(String topic, String message, String equipmentId) {
        this.topic = topic;
        this.message = message;
        this.equipmentId = equipmentId;
    }

    public String getEquipmentId() {
        return equipmentId;
    }

    public void setEquipmentId(String equipmentId) {
        this.equipmentId = equipmentId;
    }

    public String getTopic() {
        return topic;
    }

    public String getMessage() {
        return message;
    }

    public float getPm25_Data() {
        return Pm25_Data;
    }

    public float getTemperature() {
        return Temperature;
    }

    public float getCO2_Data() {
        return CO2_Data;
    }

    public float getTVOC_Data() {
        return TVOC_Data;
    }

    public float getHCHO_Data() {
        return HCHO_Data;
    }

    public float getHumidity() {
        return Humidity;
    }

    public int getPm25Level() {
        if (Pm25_Data <= 35) {
            Pm25Level = 1;
        } else if (Pm25_Data <= 75) {
            Pm25Level = 2;
        } else if (Pm25_Data <= 115) {
            Pm25Level = 3;
        } else if (Pm25_Data <= 150) {
            Pm25Level = 4;
        } else if (Pm25_Data > 150) {
            Pm25Level = 5;
        }
        return Pm25Level;
    }


    public int getCO2Level() {
        if (CO2_Data <= 350 && CO2_Data >= 250) {
            CO2Level = 1;
        } else if (CO2_Data > 350 && CO2_Data <= 1000) {
            CO2Level = 2;
        } else if (CO2_Data > 1000) {
            CO2Level = 3;
        } else if (CO2_Data > 1500) {
            CO2Level = 4;
        } else if (CO2_Data > 2000) {
            CO2Level = 5;
        }
        return CO2Level;
    }

    public int getTVOCLevel() {
        if (TVOC_Data <= 0.3) {
            TVOCLevel = 1;
        } else if (TVOC_Data > 0.3 && TVOC_Data <= 0.6) {
            TVOCLevel = 2;
        } else if (TVOC_Data > 0.6 && TVOC_Data <= 1) {
            TVOCLevel = 3;
        } else if (TVOC_Data > 1 && TVOC_Data <= 1.6) {
            TVOCLevel = 4;
        } else if (TVOC_Data > 1.6) {
            TVOCLevel = 5;
        }
        return TVOCLevel;
    }

    public int getHCHOLevel() {
        if (HCHO_Data <= 0.05) {
            HCHOLevel = 1;
        } else if (HCHO_Data > 0.05 && HCHO_Data <= 0.1) {
            HCHOLevel = 2;
        } else if (HCHO_Data > 0.1 && HCHO_Data <= 0.2) {
            HCHOLevel = 3;
        } else if (HCHO_Data > 0.2 && HCHO_Data <= 0.3) {
            HCHOLevel = 4;
        } else if (HCHO_Data > 0.3) {
            HCHOLevel = 5;
        }
        return HCHOLevel;
    }


    public int getAllLevel() {
        int[] level = new int[4];
        level[0] = getPm25Level();
        level[1] = getCO2Level();
        level[2] = getTVOCLevel();
        level[3] = getHCHOLevel();

        int max = level[0];//将数组的第一个元素赋给max
        int min = level[0];//将数组的第一个元素赋给min
        for (int i = 1; i < level.length; i++) {//从数组的第二个元素开始赋值,依次比较
            if (level[i] > max) {//如果arr[i]大于最大值,就将arr[i]赋给最大值
                max = level[i];
            }
            if (level[i] < min) {//如果arr[i]小于最小值,就将arr[i]赋给最小值
                min = level[i];
            }
        }
        return max;
    }

    public String getPm25LevelText() {
        TemperatureLevelText = "未知";
        if (isClosed) return "...";
        if (Pm25_Data <= 35) {
            Pm25LevelText = "优";
        } else if (Pm25_Data <= 75) {
            Pm25LevelText = "良";
        } else if (Pm25_Data <= 115) {
            Pm25LevelText = "轻度";
        } else if (Pm25_Data <= 150) {
            Pm25LevelText = "中度";
        } else if (Pm25_Data > 150) {
            Pm25LevelText = "中度";
        }
        return Pm25LevelText;
    }

    public String getTemperatureLevelText() {
        if (isClosed) return "...";
        TemperatureLevelText = "未知";
        if (Temperature >= 12 && Temperature <= 24) {
            TemperatureLevelText = "舒适";
        } else if (Temperature >= -10 && Temperature < 12) {
            TemperatureLevelText = "偏冷";
        } else if (Temperature < -12) {
            TemperatureLevelText = "严寒";
        } else if (Temperature <= 38 && Temperature > 24) {
            TemperatureLevelText = "偏热";
        } else if (Temperature > 38) {
            TemperatureLevelText = "炙热";
        }
        return TemperatureLevelText;
    }

    public String getCO2LevelText() {
        if (isClosed) return "...";
        CO2LevelText = "未知";
        if (CO2_Data <= 350) {
            CO2LevelText = "清新";
        } else if (CO2_Data > 350 && CO2_Data <= 1000) {
            CO2LevelText = "较好";
        } else if (CO2_Data > 1000) {
            CO2LevelText = "较浑浊";
        } else if (CO2_Data > 1500) {
            CO2LevelText = "浑浊";
        } else if (CO2_Data > 2000) {
            CO2LevelText = "严重";
        }
        return CO2LevelText;
    }

    public String getTVOCLevelText() {
        if (isClosed) return "...";
        TVOCLevelText = "未知";
        if (TVOC_Data <= 0.3) {
            TVOCLevelText = "较好";
        } else if (TVOC_Data > 0.3 && TVOC_Data <= 0.6) {
            TVOCLevelText = "良";
        } else if (TVOC_Data > 0.6 && TVOC_Data <= 1) {
            TVOCLevelText = "轻度";
        } else if (TVOC_Data > 1 && TVOC_Data <= 1.6) {
            TVOCLevelText = "中度";
        } else if (TVOC_Data > 1.6) {
            TVOCLevelText = "重度";
        }
        return TVOCLevelText;
    }

    public String getHCHOLevelText() {
        if (isClosed) return "...";
        HCHOLevelText = "未知";
        if (HCHO_Data <= 0.05) {
            HCHOLevelText = "优";
        } else if (HCHO_Data > 0.05 && HCHO_Data <= 0.1) {
            HCHOLevelText = "良";
        } else if (HCHO_Data > 0.1 && HCHO_Data <= 0.2) {
            HCHOLevelText = "轻度";
        } else if (HCHO_Data > 0.2 && HCHO_Data <= 0.3) {
            HCHOLevelText = "中度";
        } else if (HCHO_Data > 0.3) {
            HCHOLevelText = "重度";
        }
        return HCHOLevelText;
    }

    public String getAllLevelText() {
        if (isClosed) return "...";
        AllLevelText = "未知";
        int[] level = new int[4];
        level[0] = getPm25Level();
        level[1] = getCO2Level();
        level[2] = getTVOCLevel();
        level[3] = getHCHOLevel();
        int max = level[0];//将数组的第一个元素赋给max
        for (int i = 1; i < level.length; i++) {//从数组的第二个元素开始赋值,依次比较
            if (level[i] > max) {//如果arr[i]大于最大值,就将arr[i]赋给最大值
                max = level[i];
            }
        }
        if (max == 1) {
            AllLevelText = "优";
        } else if (max == 2) {
            AllLevelText = "良";
        } else if (max == 3) {
            AllLevelText = "中";
        } else if (max == 4) {
            AllLevelText = "较差";
        } else if (max == 5) {
            AllLevelText = "差";
        }
        return AllLevelText;
    }

    public String getHumidityLevelText() {
        if (isClosed) return "...";
        if (Humidity <= 30) {
            HumidityLevelText = "偏干";
        } else if (Humidity > 30 && Humidity <= 60) {
            HumidityLevelText = "舒适";
        } else if (Humidity > 60) {
            HumidityLevelText = "偏湿气";
        }
        return HumidityLevelText;
    }

    @Override
    public String toString() {
        return "MqttMsg{" +
                "topic='" + topic + '\'' +
                ", message='" + message + '\'' +
                ", Pm25_Data=" + Pm25_Data +
                ", Temperature=" + Temperature +
                ", CO2_Data=" + CO2_Data +
                ", TVOC_Data=" + TVOC_Data +
                ", HCHO_Data=" + HCHO_Data +
                ", Humidity=" + Humidity +
                ", ModeState=" + ModeState +
                ", light=" + light +
                ", ScreenStatus=" + ScreenStatus +
                ", Pm25Level=" + Pm25Level +
                ", TemperatureLevel=" + TemperatureLevel +
                ", CO2Level=" + CO2Level +
                ", TVOCLevel=" + TVOCLevel +
                ", HCHOLevel=" + HCHOLevel +
                ", HumidityLevel=" + HumidityLevel +
                ", AllLevel=" + AllLevel +
                ", Pm25LevelText='" + Pm25LevelText + '\'' +
                ", TemperatureLevelText='" + TemperatureLevelText + '\'' +
                ", CO2LevelText='" + CO2LevelText + '\'' +
                ", TVOCLevelText='" + TVOCLevelText + '\'' +
                ", HCHOLevelText='" + HCHOLevelText + '\'' +
                ", HumidityLevelText='" + HumidityLevelText + '\'' +
                ", AllLevelText='" + AllLevelText + '\'' +
                ", isClosed=" + isClosed +
                ", clock1='" + clock1 + '\'' +
                ", clock2='" + clock2 + '\'' +
                ", clock3='" + clock3 + '\'' +
                ", clock1On=" + clock1On +
                ", clock2On=" + clock2On +
                ", clock3On=" + clock3On +
                ", plug='" + plug + '\'' +
                ", equipmentId='" + equipmentId + '\'' +
                '}';
    }

    @Override
    public int hashCode() {
        return equipmentId.length();
    }

    @Override
    public boolean equals(Object obj) {
        return this.equipmentId.equals(((MqttMsg) obj).equipmentId);
    }
}

step7:

package com.example.demoanalytic


import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.support.v4.app.NotificationCompat
import android.text.TextUtils
import android.util.Log
import com.blankj.utilcode.util.ServiceUtils
import com.blankj.utilcode.util.TimeUtils
import com.rairmmd.andmqtt.*
import org.eclipse.paho.android.service.MqttTraceHandler
import org.eclipse.paho.client.mqttv3.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode


class MQTTService : Service() {
    private var mqttMsg: MqttMsg? = null
    private var isStop = false

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(
                NotificationChannel(
                    "faceId",
                    "mqtt",
                    NotificationManager.IMPORTANCE_DEFAULT
                )
            )
            val builder = NotificationCompat.Builder(this, "faceId")
            startForeground(1, builder.build())
        }
        EventBus.getDefault().register(this)
        if (UserZone.isLogin(this)) {
            Log.e("MQTTService", "onCreate 开始连接")
            initMqtt2()
        }
    }


    private fun initMqtt2() {
        AndMqtt.getInstance().init(applicationContext)
        AndMqtt.getInstance().connect(
            MqttConnect().setClientId(UserZone.getClientId(this))
                .setPort(MQTT_PORT).setAutoReconnect(true)
                .setCleanSession(true).setServer(MQTT_SERVICE)
                .setTraceCallback(object : MqttTraceHandler {
                    override fun traceDebug(tag: String, message: String) {
                        Log.e("MQTTService", "调试信息:$tag,$message")
                    }

                    override fun traceError(tag: String, message: String) {
                        Log.e("MQTTService", "错误信息:$tag,$message")
                    }

                    override fun traceException(
                        tag: String,
                        message: String,
                        e: java.lang.Exception
                    ) {
                        Log.e("MQTTService", "异常信息:$tag,$message,$e")
                    }
                }).setMessageListener(object : MqttCallbackExtended {
                    override fun connectComplete(
                        reconnect: Boolean,
                        serverURI: String
                    ) {
                        //reconnect 如果为真,则连接是自动重新连接的结果
                        Log.e("MQTTService", "连接完成:$reconnect,$serverURI")
                    }

                    override fun connectionLost(cause: Throwable) {
                        Log.e("MQTTService", "连接丢失:$cause")
                    }

                    @Throws(java.lang.Exception::class)
                    override fun messageArrived(
                        topic: String,
                        message: MqttMessage
                    ) {
                        Log.e("MQTTService", "接收到服务端的数据:$topic,$message")
                    }

                    override fun deliveryComplete(token: IMqttDeliveryToken) {
                        Log.e("MQTTService", "当消息的传递完成时调用:$token")

                    }
                }), object : IMqttActionListener {
                override fun onSuccess(asyncActionToken: IMqttToken) {
                    Log.e("Rair", "(MainActivity.java:51)-onSuccess:->连接成功")
                }

                override fun onFailure(
                    asyncActionToken: IMqttToken,
                    exception: Throwable
                ) {
                    Log.e("Rair", "(MainActivity.java:56)-onFailure:->连接失败")
                }
            })
    }



    private fun writeLog(log: String) {
        // FileUtils.writeFileFromString("/sdcard/mindor.txt", log, true)
    }

    private fun publish(msg: String, topic: String) {
        if (!AndMqtt.getInstance().isConnect) {
            // Toaster.show("设备连接异常,请重启应用或稍后再试")
            Log.e("MQTTService", "publish 开始连接")
            initMqtt2()
            return
        }
        //发布
        AndMqtt.getInstance().publish(MqttPublish()
            .setMsg(msg)
            .setQos(0)
            .setTopic(topic), object : IMqttActionListener {
            override fun onSuccess(asyncActionToken: IMqttToken) {
                Log.e("publish onSuccess", topic + "发布成功" + msg + asyncActionToken.isComplete)
                val log = TimeUtils.getNowString() + "发送成功-->红外主题${topic}---消息${msg}\n\n"
                writeLog(log)
            }

            override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
                Log.e("publish onSuccess", "发布失败onFailure")
            }
        })

    }

    private fun subscribe(topic: String) {
        if (!AndMqtt.getInstance().isConnect) {
            //Toaster.show("设备连接异常,请重启应用或稍后再试")
            Log.e("MQTTService", "subscribe 开始连接")
            initMqtt2()
            return
        }
        //订阅
        AndMqtt.getInstance().subscribe(MqttSubscribe()
            .setTopic(topic)
            .setQos(0), object : IMqttActionListener {
            override fun onSuccess(asyncActionToken: IMqttToken) {
                Log.e("MQTTService", "(MainActivity.java:63)-onSuccess:->订阅成功")
            }

            override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
                Log.e("MQTTService", "(MainActivity.java:68)-onFailure:->订阅失败")
            }
        })
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun publishMsg(mqtt: MqttBean) {
        Log.e("MQTTService", "发送指令publishMsg:${mqtt.topic}")
        if (mqtt.register) {
            subscribe(mqtt.topic)
            return
        }
        if (mqtt.isUnregister) {
            unSubscribe(mqtt.topic)
            return
        }
        publish(mqtt.message, mqtt.topic)
    }


    private fun unSubscribe(topic: String?) {
        try {
            if (!AndMqtt.getInstance().isConnect) {
                return
            }
            if (TextUtils.isEmpty(topic)) return
            AndMqtt.getInstance().unSubscribe(MqttUnSubscribe()
                .setTopic(topic), object : IMqttActionListener {
                override fun onSuccess(asyncActionToken: IMqttToken) {
                    Log.e("MQTTService", topic + "(MainActivity.java:93)-onSuccess:->取消订阅成功")
                }

                override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
                    Log.e("MQTTService", topic + "(MainActivity.java:98)-onFailure:->取消订阅失败")
                }
            })
        } catch (e: Exception) {

        }

    }

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
    }


    @Subscribe()
    fun stopService(stopService: StopService) {
        this.isStop = stopService.isStop
    }

    @Subscribe
    fun loginSuccess(userInfo: UserInfo) {
        Log.e("MQTTService", "loginSuccess 开始连接")
        initMqtt2()
    }
}

step8:

package com.example.demoanalytic;


import java.io.Serializable;

public class ShowMsg implements Serializable {
}

step9:

package com.example.demoanalytic;


        import java.io.Serializable;

public class StopService implements Serializable {
    public boolean isStop;

    public StopService(boolean isStop) {
        this.isStop = isStop;
    }
}

step10:

package com.example.demoanalytic;


        import java.io.Serializable;

public class UserInfo implements Serializable {

    /**
     * birthday : 2018-2-5
     * phone : 110
     * sex : 0
     * address : 北京
     * nickName : 12
     * userId : minApp100001
     * headPortrait : null
     */

    private String birthday;
    private String phone;
    private String sex;
    private String address;
    private String nickName;
    private String userId;
    private String headPortrait;
    private String ClientId;

    public String getClientId() {
        return ClientId;
    }

    public void setClientId(String clientId) {
        ClientId = clientId;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getHeadPortrait() {
        return headPortrait;
    }

    public void setHeadPortrait(String headPortrait) {
        this.headPortrait = headPortrait;
    }
}

step11:

package com.example.demoanalytic

import android.content.Context
import android.text.TextUtils
import com.google.gson.Gson


object UserZone {

    /**
     *是否已登录
     * */
    fun isLogin(context: Context): Boolean {
        return true
    }

    /**
     *获取当前登录的用户id
     * */
    fun getClientId(context: Context): String {
        /*return if (TextUtils.isEmpty(clientId)) {
            userId
        } else {
            clientId!!
        }*/
        return "minApp125106"
    }
}

end