IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android MQTT客户端 -> 正文阅读

[移动开发]Android MQTT客户端

目的是为了实时监控室外广告屏的亮度,界面,声音,开关机等等…… 因为室外的网络情况是随时可变的,所以采用的MQTT协议,作为Android客户端来说因为用MQTT发送消息太繁琐,我们采用的是客户端只接收命令,然后用Http进行数据反馈,这个项目近期也做完了,故记录一下。

第一步:导入在线库

// mqtt 包导入
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'

第二步:声明广播(这个是在线库自带的 直接这么写就行,不用自己写这个service)

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

第三步:MqttManager的全部代码

public class MqttManager {
    public final static String TAG = MqttManager.class.getSimpleName();

    @SuppressLint("StaticFieldLeak")
    private static volatile MqttManager mInstance = null;
    private MqttCallback mCallback;
    public MqttClient client;
    private MqttConnectOptions conOpt;
    private Context context;
    public String[] topic;

    private MqttManager(Context context) {
        mCallback = new MqttCallbackBus(context);
        this.context = context;
    }

    public static MqttManager getInstance(Context context) {
        if (mInstance == null) {
            synchronized (MqttManager.class) {
                if (mInstance == null) {
                    mInstance = new MqttManager(context);
                }
            }
        }
        return mInstance;
    }

    /**
     * 释放单例, 及其所引用的资源
     */
    public static void release() {
        try {
            if (mInstance != null) {
                mInstance.disConnect();
                mInstance = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建Mqtt 连接
     *
     * @param brokerUrl Mqtt服务器地址(tcp://xxxx:1863)
     * @param userName  用户名
     * @param password  密码
     * @return
     */
    public boolean createConnect(String brokerUrl, String userName, String password) {
        topic = new String[]{PUBLISH_TOPIC};
        String deviceId = Utils.getDeviceNo();
        if (client != null && client.isConnected()) {
            return true;
        }
        boolean flag = false;
        try {
            conOpt = new MqttConnectOptions();
            conOpt.setCleanSession(true); //不接收离线期间的消息  每次都是重新登陆
            conOpt.setAutomaticReconnect(true); //自动重连
            if (!TextUtils.isEmpty(password)) {
                conOpt.setPassword(password.toCharArray());
            }
            if (!TextUtils.isEmpty(userName)) {
                conOpt.setUserName(userName);
            }
            client = new MqttClient(brokerUrl, deviceId, new MemoryPersistence());
            client.setCallback(mCallback);
            flag = doConnect();
            client.subscribe(topic);
        } catch (MqttException e) {
            e.printStackTrace();
            //重连
            String msg = "exception_reconnect";
            EventBus.getDefault().post(msg);
        }
        return flag;
    }

    /**
     * 建立连接
     *
     * @return
     */
    private boolean doConnect() {
        boolean flag = false;
        if (client != null) {
            try {
                client.connect(conOpt);
                flag = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return flag;
    }

    public boolean publish(String topicName, int qos, byte[] payload) {
        boolean flag = false;
        try {
            if (client == null) {
                createConnect(HOST, USERNAME, PASSWORD);
            }
            if (!client.isConnected()) {
                this.reconnect();
            }
            MqttMessage message = new MqttMessage(payload);
            message.setQos(qos);
            client.publish(topicName, message);
            flag = true;
        } catch (MqttException e) {
            e.printStackTrace();
        }
        return flag;
    }


    private boolean subscribe(String topicName, int qos) {
        boolean flag = false;
        if (client != null && client.isConnected()) {
            try {
                client.subscribe(topicName, qos);
                flag = true;
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
        return flag;
    }

    private boolean subscribe(String[] topicName, int qos[]) {
        boolean flag = false;
        if (client != null && client.isConnected()) {
            try {
                client.subscribe(topicName, qos);
                flag = true;
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
        return flag;
    }


    /**
     * 取消连接
     *
     * @throws MqttException
     */
    public void disConnect() throws MqttException {
        if (client != null && client.isConnected()) {
            client.disconnect();
        }
    }

    /**
     * 关闭连接
     */
    public void close() {
        if (client != null && client.isConnected()) {
            try {
                client.disconnect();
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 重新连接
     */
    private void reconnect() {
        if (client != null && !client.isConnected()) {
            try {
                client.setCallback(mCallback);
                client.connect(conOpt);
                client.subscribe(topic);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }
}

里面用eventBus做了下重连处理,后续响应如下

boolean isHavNet = isConnectIsNomarl(); //判断是否有网
if (isHavNet) {
    handler.removeMessages(4);
    MqttManager.getInstance(BaseApplication.getContext()).createConnect(HOST, USERNAME, PASSWORD);
}else{
    handler.sendEmptyMessageDelayed(4, 10000);//无网等待有网再连
}

第四步:mqtt消息回调类

public class MqttCallbackBus implements MqttCallbackExtended {

    private Context mContext;

    public MqttCallbackBus(Context context) {
        this.mContext = context;
    }

    @Override
    public void connectComplete(boolean reconnect, String serverURI) {
        Log.e("MqttCallbackBus", "MQTT_connectComplete:");
        //断开连接必须重新订阅才能收到之前订阅的session连接的消息
        if(reconnect){
            Log.e("MqttCallbackBus_重连订阅主题", "MQTT_connectComplete:");
            //这里是发送消息去重新订阅
            String msg = "reconnect";
            EventBus.getDefault().postSticky(msg);
        }
    }

    @Override
    public void connectionLost(Throwable cause) { //掉线
        Log.e("MqttCallbackBus>>>", "MQTT_connectionLost 掉线原因:"+cause.getMessage());
        cause.printStackTrace();
    }

    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        MqttReceivedMessage msg = (MqttReceivedMessage) message;
        String s = msg.toString();
        Log.e("MQTT_messageArrived_msg", "MQTT_msg"+topic);
        HashMap hs = new Gson().fromJson(s, HashMap.class);
        EventBus.getDefault().post(hs); //抛出收到的消息 eventbus响应做自己的业务处理
    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken token) { //(发布)publish后会执行到这里,发送状态 token.isComplete()
        Log.e("MqttCallbackBus>>>", "MQTT_deliveryComplete:");
    }
}

其中connectComplete的重连回调reconnect = true 的eventbus的响应是:

//重连  能进重连  说明必有网了  不必再else 定时重试网络
    String[] topic = new String[]{PUBLISH_TOPIC};
    try {
        MqttManager.getInstance(BaseApplication.getContext()).client.subscribe(topic);
    } catch (MqttException e) {
        e.printStackTrace();
    }

MainActivity的使用如下:

//网络变化监听  首次连接mqtt
    boolean isHavNet = isConnectIsNomarl();
    if (isHavNet) {
        handler.removeMessages(1);
        MqttManager.getInstance(BaseApplication.getContext()).createConnect(HOST, USERNAME, PASSWORD);
    } else {
        handler.sendEmptyMessageDelayed(1, 5000);
    }

MQTT全局的配置参数:

?

附赠个判断是否有网的工具类

/**
 * 判断网络是否连接
 */
private boolean isConnectIsNomarl() {
    ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    @SuppressLint("MissingPermission") NetworkInfo info = connectivityManager.getActiveNetworkInfo();

    if (info != null && info.isConnected()) {
        String name = info.getTypeName();
        return true;
    } else {
        return false;
    }
}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 16:26:11  更:2022-03-03 16:29:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 17:04:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码