Android Studio开发手机APP(三)-MQTT通信优化

Android Studio开发手机APP(三)-MQTT通信优化

之前我们写了一个MQTT通信的APP,使用了org.eclipse.paho.client.mqttv3-1.2.0这个jar包,最后实现了MQTT连接到服务端,但是,我们在使用的时候会发现,你是否连接成功,需要我们自己去查询,并且,他掉线后是不会自动重连的,所以这就导致我们需要不断的去查询MQTT是否正在连接。

一、下载并导入另一个jar包

那么有没有很好的解决办法呢,当然是有的,在之前我们提供的jar包官方下载地址有这样org.eclipse.paho.android.service一个jar包,我们可以上面标着android字样,对,就是他,我们将其下载下来。
在这里插入图片描述
这里我下载的是1.1.1版本的:
在这里插入图片描述
然后将其导入到Android Studio工程中,记住,两个jar包都要导入。

二、添加权限

jar包导入后我们需要添加另一个权限:

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

还要添加MQTT服务

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

添加完如下所示:
在这里插入图片描述

三、修改代码

然后我们来修改之前的代码:
首先,将mqtt_client对象的类型修改为MqttAndroidClient,

private MqttAndroidClient mqtt_client;                   //创建一个mqtt_client对象

然后将对象实例化的方法也改成MqttAndroidClient,

mqtt_client = new MqttAndroidClient(getApplicationContext(),serverUri,clientId);

再就是连接回调函数,可以使用一个扩展了的类MqttCallbackExtended,然后添加连接成功方法:

 mqtt_client.setCallback(new MqttCallbackExtended() {
	@Override
	public void connectComplete(boolean reconnect, String serverURI) {
	    //连接成功
	    makeToast("connected sussces");
    }
}

这样我们就完成了。

四、重连测试

首先我们查看一下EMQ平台上的连接状态,注意,客户端ID和连接时间
在这里插入图片描述
我们将手机的wifi和数据流量断开,可以看到提示:
在这里插入图片描述

然后,EMQ平台上也可以看到,我们的APP已经没有连接了:
在这里插入图片描述
现在,我们将手机的wifi或者数据连接打开,不要退出APP,可以看到:
在这里插入图片描述
然后在EMQ平台上:
在这里插入图片描述
我们可以看到,客户端ID是没有变的,但是我们的连接时间改变了,之前我说过,客户端ID是app+当前时间,也就是创建clientId变量的时间,也就是说,我并没有退出这个APP,然后我们实现了MQTT的重连。

五、代码

最后,将整个Java主程序代码贴上:

package com.example.iot_mqtt;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.Toast;

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.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;

public class MainActivity extends AppCompatActivity {
    private String serverUri = "tcp://127.0.0.1:1883";  //这里可以填上各种物联网云平台的域名+1883端口号,注意:前缀“tcp://”不可少,之前我没写,怎么都连不上,折腾了好久
    private String userName = "android";                    //然后是你的用户名,阿里云腾讯云百度云天工物接入这些平台你新建设备后就自动生成了
    private String passWord = "1234567";                    //用户名对应的密码,同样各种云平台都会对应生成密码,这里我的EMQ平台没做限制,所以用户名和密码可以随便填写
    private String clientId = "app"+System.currentTimeMillis(); //clientId很重要,不能重复,否则就会连不上,所以我定义成 app+当前时间
    private String mqtt_sub_topic = "Android_Get";          //需要订阅的主题
    private String mqtt_pub_topic = "Android_Set";          //需要发布的主题

    private MqttAndroidClient mqtt_client;                   //创建一个mqtt_client对象


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

        mqtt_init_Connect();
    }

    public void mqtt_init_Connect()
    {
        try {
            //实例化mqtt_client,第一个参数是app的上下文,直接填入就行,然后填入我们定义的serverUri和clientId
            mqtt_client = new MqttAndroidClient(getApplicationContext(),serverUri,clientId);
            //创建并实例化一个MQTT的连接参数对象
            MqttConnectOptions options = new MqttConnectOptions();
            //然后设置对应的参数
            options.setUserName(userName);                  //设置连接的用户名
            options.setPassword(passWord.toCharArray());    //设置连接的密码
            options.setConnectionTimeout(30);               // 设置超时时间,单位为秒
            options.setKeepAliveInterval(60);               //设置心跳,30s
            options.setAutomaticReconnect(true);            //是否重连
            //设置是否清空session,设置为false表示服务器会保留客户端的连接记录,设置为true表示每次连接到服务器都以新的身份连接
            options.setCleanSession(true);

            //设置回调
            mqtt_client.setCallback(new MqttCallbackExtended() {
                @Override
                public void connectComplete(boolean reconnect, String serverURI) {
                    //连接成功
                    makeToast("connected sussces");
                }
                @Override
                public void connectionLost(Throwable cause) {
                    //连接丢失后,一般在这里面进行重连
                    makeToast("connection Lost");
                }
                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    //publish后会执行到这里
                }
                @Override
                public void messageArrived(String topicName, MqttMessage message) throws Exception {
                    //subscribe后得到的消息会执行到这里面
                }
            });

            mqtt_client.connect(options);

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void makeToast(String toast_str) {
        Toast.makeText(MainActivity.this, toast_str, Toast.LENGTH_LONG).show();
    }

}

发布了62 篇原创文章 · 获赞 13 · 访问量 5572

猜你喜欢

转载自blog.csdn.net/qq_38113006/article/details/104951337