美文网首页
android MQTT通信 简单使用

android MQTT通信 简单使用

作者: GoodWen | 来源:发表于2019-08-28 15:09 被阅读0次

    一,在app下的build.gradle中添加如下引用

        implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'//mqtt相关
        implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'//mqtt相关
        implementation 'org.greenrobot:eventbus:3.1.1'//eventBus  为了传数据会UI界面
    

    二,AndroidManifest.xml中添加权限

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

    在application中添加如下代码

       <service android:name="org.eclipse.paho.android.service.MqttService" /> <!--MqttService-->
       <service android:name=".service.MyMqttService"/> <!--MyMqttService  自己写的服务  后面会讲-->
    

    三,MyMqttService类

    public class MyMqttService extends Service {
    
        public final String TAG = MyMqttService.class.getSimpleName();
        private static MqttAndroidClient mqttAndroidClient;
        private MqttConnectOptions mMqttConnectOptions;
        public String HOST = "tcp://192.168.101.115:1883";//服务器地址(协议+地址+端口号)
        public String USERNAME = "admin";//用户名
        public String PASSWORD = "admin";//密码
        public static String PUBLISH_TOPIC = "tourist_enter";//发布主题
        public static String RESPONSE_TOPIC = "message_arrived";//响应主题
        public String CLIENTID = "zhangrenwen";
    //    public String CLIENTID = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
    //            ? Build.getSerial() : Build.SERIAL;//客户端ID,一般以客户端唯一标识符表示,这里用设备序列号表示
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            init();
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        /**
         * 开启服务
         */
        public static void startService(Context mContext) {
            mContext.startService(new Intent(mContext, MyMqttService.class));
        }
    
        /**
         * 发布 (模拟其他客户端发布消息)
         *
         * @param message 消息
         */
        public static void publish(String message) {
            String topic = PUBLISH_TOPIC;
            Integer qos = 2;
            Boolean retained = false;
            try {
                //参数分别为:主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息
                mqttAndroidClient.publish(topic, message.getBytes("GBK"), qos.intValue(), retained.booleanValue());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 响应 (收到其他客户端的消息后,响应给对方告知消息已到达或者消息有问题等)
         *
         * @param message 消息
         */
        public void response(String message) {
            String topic = RESPONSE_TOPIC;
            Integer qos = 2;
            Boolean retained = false;
            try {
                //参数分别为:主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息
                mqttAndroidClient.publish(topic, message.getBytes(), qos.intValue(), retained.booleanValue());
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 初始化
         */
        private void init() {
            String serverURI = HOST; //服务器地址(协议+地址+端口号)
            mqttAndroidClient = new MqttAndroidClient(this, serverURI, CLIENTID);
            mqttAndroidClient.setCallback(mqttCallback); //设置监听订阅消息的回调
            mMqttConnectOptions = new MqttConnectOptions();
            mMqttConnectOptions.setCleanSession(true); //设置是否清除缓存
            mMqttConnectOptions.setConnectionTimeout(10); //设置超时时间,单位:秒
            mMqttConnectOptions.setKeepAliveInterval(20); //设置心跳包发送间隔,单位:秒
            mMqttConnectOptions.setUserName(USERNAME); //设置用户名
            mMqttConnectOptions.setPassword(PASSWORD.toCharArray()); //设置密码
    
            // last will message
            boolean doConnect = true;
            String message = "{\"terminal_uid\":\"" + CLIENTID + "\"}";
            String topic = PUBLISH_TOPIC;
            Integer qos = 2;
            Boolean retained = false;
            if ((!message.equals("")) || (!topic.equals(""))) {
                // 最后的遗嘱
                try {
                    mMqttConnectOptions.setWill(topic, message.getBytes(), qos.intValue(), retained.booleanValue());
                } catch (Exception e) {
                    Log.i(TAG, "Exception Occured", e);
                    doConnect = false;
                    iMqttActionListener.onFailure(null, e);
                }
            }
            if (doConnect) {
                doClientConnection();
            }
        }
    
        /**
         * 连接MQTT服务器
         */
        private void doClientConnection() {
            if (!mqttAndroidClient.isConnected() && isConnectIsNomarl()) {
                try {
                    mqttAndroidClient.connect(mMqttConnectOptions, null, iMqttActionListener);
                } catch (MqttException e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * 判断网络是否连接
         */
        private boolean isConnectIsNomarl() {
            ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo info = connectivityManager.getActiveNetworkInfo();
            if (info != null && info.isAvailable()) {
                String name = info.getTypeName();
                Log.i(TAG, "当前网络名称:" + name);
                return true;
            } else {
                Log.i(TAG, "没有可用网络");
                /*没有可用网络的时候,延迟3秒再尝试重连*/
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        doClientConnection();
                    }
                }, 3000);
                return false;
            }
        }
    
        //MQTT是否连接成功的监听
        private IMqttActionListener iMqttActionListener = new IMqttActionListener() {
    
            @Override
            public void onSuccess(IMqttToken arg0) {
                Log.i(TAG, "连接成功 ");
                try {
                    mqttAndroidClient.subscribe(PUBLISH_TOPIC, 2);//订阅主题,参数:主题、服务质量
                } catch (MqttException e) {
                    e.printStackTrace();
                }
            }
    
            @Override
            public void onFailure(IMqttToken arg0, Throwable arg1) {
                arg1.printStackTrace();
                Log.i(TAG, "连接失败 ");
                doClientConnection();//连接失败,重连(可关闭服务器进行模拟)
            }
        };
    
        //订阅主题的回调
        private MqttCallback mqttCallback = new MqttCallback() {
    
            @Override
            public void messageArrived(String topic, MqttMessage message) throws Exception {
                Log.i(TAG, "收到消息: " + topic + new String(message.getPayload(),"GBK"));
                EventBus.getDefault().post(new UpdateTextEvent(new String(message.getPayload(),"GBK")));
                //收到消息,这里弹出Toast表示。如果需要更新UI,可以使用广播或者EventBus进行发送
    //            Toast.makeText(getApplicationContext(), "messageArrived: " + new String(message.getPayload()), Toast.LENGTH_LONG).show();
                //收到其他客户端的消息后,响应给对方告知消息已到达或者消息有问题等
                response("message arrived");
            }
    
    
            @Override
            public void deliveryComplete(IMqttDeliveryToken arg0) {
    
            }
    
            @Override
            public void connectionLost(Throwable arg0) {
                Log.i(TAG, "连接断开 ");
                doClientConnection();//连接断开,重连
            }
        };
    
        @Override
        public void onDestroy() {
            try {
                mqttAndroidClient.disconnect(); //断开连接
                Log.i(TAG, "onDestroy: 服务关闭");
            } catch (MqttException e) {
                e.printStackTrace();
            }
            super.onDestroy();
        }
    }
    

    四,封装数据bean类

    public class UpdateTextEvent {
        private static final String TAG = "AA";
        private String msg;
    
        public UpdateTextEvent(String msg) {
            this.msg = msg;
            Log.i(TAG, "updateTextEvent: " + msg);
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    }
    

    五,activity_main.xml布局

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.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/editText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="发送"
            app:layout_constraintTop_toBottomOf="@+id/editText"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            />
        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintTop_toBottomOf="@+id/button"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            />
    
    </android.support.constraint.ConstraintLayout>
    

    六,MainActivity代码

    public class MainActivity extends AppCompatActivity {
    
        TextView textView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            final EditText editText = findViewById(R.id.editText);
    
            textView = findViewById(R.id.textView);
            MyMqttService.startService(this); //开启服务
            findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    MyMqttService.publish(editText.getText().toString());
                }
            });
        }
    
        /**
         * 订阅的过程中,默认是在主线程中用到的
         */
        @Subscribe(threadMode = ThreadMode.MAIN)
        public void modifyBtn4(UpdateTextEvent msg) {
            textView.setText("收到的消息:"+msg.getMsg());
        }
    
        @Override
        public void onStart() {
            super.onStart();
            //在事件被订阅的界面中注册EventBus
            EventBus.getDefault().register(this);
        }
    
        @Override
        public void onStop() {
            super.onStop();
            //注销EventBus
            EventBus.getDefault().unregister(this);
        }
    }
    

    至此 已经完毕 但是想要测试效果请联系后台
    我们根据后台修改以下框框内容就好


    QQ截图20190828151833.png

    相关文章

      网友评论

          本文标题:android MQTT通信 简单使用

          本文链接:https://www.haomeiwen.com/subject/uvapectx.html