Android原生 MQTT开发

一、引包

1.1.模块的build.gradle

    //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'implementation 'org.bouncycastle:bcpkix-jdk15on:1.59'

1.2 旧版AndroidStudio开发工具在项目的guild.gradle引入

   maven {url "https://repo.eclipse.org/content/repositories/paho-snapshots/"}

1.3 新版则在setting.gradle引入

   maven {url "https://repo.eclipse.org/content/repositories/paho-snapshots/"}

二、工具类封装


/*** mqtt* 服务*/public class XyMqttService extends Service {public final static String TAG = "数据处理";public static MqttAndroidClient mqttAndroidClient;private static MqttConnectOptions mMqttConnectOptions;//wss://z66811d5.ala.cn-hangzhou.emqxsl.cn:8084/mqttpublic static String HOST = "tcp://www.....:1883";//服务器地址(协议+地址+端口号)
//    public static String HOST = "tcp://.........n:8883";//服务器地址(协议+地址+端口号)public String USERNAME = "xiaoya";//用户名public String PASSWORD = "xiaoya";//密码public static String PUBLISH_TOPIC = "xiaoya/video/pull/1";//发布主题public static String RESPONSE_TOPIC = "xiaoya/video/1111";//响应主题public String CLIENTID = "safffadasaafqedq2";//设备唯一标识/*** 订阅主题:* 小雅视频拉取:xiaoya/video/pull/+* 小雅视频通话:xiaoya/video/chat/+*/@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {init();return START_NOT_STICKY;//非粘性的 service强制杀死后,不会尝试重新启动service}@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}/*** 开启服务*/public static void startService(Context mContext) {mContext.startService(new Intent(mContext, XyMqttService.class));}/*** 发布 (模拟其他客户端发布消息)** @param message 消息*/public static void publish(String message) {String topic = PUBLISH_TOPIC;Integer qos = 1;Boolean retained = false;try {//参数分别为:主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息mqttAndroidClient.publish(topic, message.getBytes(), qos.intValue(), retained.booleanValue());} catch (MqttException e) {e.printStackTrace();}}/*** 响应 (收到其他客户端的消息后,响应给对方告知消息已到达或者消息有问题等)** @param message 消息*/public static void response(String message) {String topic = RESPONSE_TOPIC;Integer qos = 1;Boolean retained = false;try {//参数分别为:主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息mqttAndroidClient.publish(topic, message.getBytes(), qos.intValue(), retained.booleanValue());} catch (MqttException e) {e.printStackTrace();}}/*** 初始化*/private void init() {String serverURI = HOST; //服务器地址(协议+地址+端口号)Logger.d("==初始化MQ:" + serverURI);if (mqttAndroidClient == null) {mqttAndroidClient = new MqttAndroidClient(this, serverURI, CLIENTID);mqttAndroidClient.setCallback(mqttCallback); //设置监听订阅消息的回调}if (mMqttConnectOptions == null) {mMqttConnectOptions = new MqttConnectOptions();try {
//                InputStream caCrtFileI = getResources().openRawResource(R.raw.ca);
//                mMqttConnectOptions.setSocketFactory(getSingleSocketFactory(caCrtFileI));mMqttConnectOptions.setCleanSession(true); //设置是否清除缓存mMqttConnectOptions.setConnectionTimeout(10); //设置超时时间,单位:秒mMqttConnectOptions.setKeepAliveInterval(20); //设置心跳包发送间隔,单位:秒mMqttConnectOptions.setUserName(USERNAME); //设置用户名mMqttConnectOptions.setPassword(PASSWORD.toCharArray()); //设置密码} catch (Exception e) {e.printStackTrace();}}// last will messageboolean doConnect = true;String message = "{\"status\":\"" + CLIENTID + "\"}";String topic = PUBLISH_TOPIC;Integer qos = 1;Boolean retained = true;if ((!message.equals("")) || (!topic.equals(""))) {// 最后的遗嘱try {mMqttConnectOptions.setWill(topic, message.getBytes(), qos.intValue(), retained.booleanValue());} catch (Exception e) {Logger.i("==Exception Occured==");doConnect = false;iMqttActionListener.onFailure(null, e);}}if (doConnect) {doClientConnection();}}/*** 连接MQTT服务器*/private static void doClientConnection() {try {if (!mqttAndroidClient.isConnected() && isConnectIsNomarl()) {Logger.d("====连接MQTT服务器===" + HOST);mqttAndroidClient.connect(mMqttConnectOptions, null, iMqttActionListener);}} catch (Exception e) {e.printStackTrace();}}/*** 判断网络是否连接*/private static boolean isConnectIsNomarl() {ConnectivityManager connectivityManager = (ConnectivityManager) XiaoYaApp.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo info = connectivityManager.getActiveNetworkInfo();if (info != null && info.isAvailable()) {String name = info.getTypeName();Logger.d("===当前网络名称:" + name);return true;} else {Logger.d("===没有可用网络===");/*没有可用网络的时候,延迟3秒再尝试重连*/new Handler().postDelayed(new Runnable() {@Overridepublic void run() {Logger.d("===没有可用网络doClientConnection===");doClientConnection();}}, 3000);return false;}}//MQTT是否连接成功的监听private static IMqttActionListener iMqttActionListener = new IMqttActionListener() {@Overridepublic void onSuccess(IMqttToken arg0) {Logger.d("==mqtt连接成功 " + HOST);try {if (mqttAndroidClient != null) {mqttAndroidClient.subscribe(PUBLISH_TOPIC, 1);//订阅主题,参数:主题、服务质量}} catch (Exception e) {e.printStackTrace();}}@Overridepublic void onFailure(IMqttToken arg0, Throwable arg1) {arg1.printStackTrace();Logger.d("==mqtt连接失败 ==" + arg1);doClientConnection();//连接失败,重连(可关闭服务器进行模拟)}};//订阅主题的回调private MqttCallback mqttCallback = new MqttCallback() {@Overridepublic void messageArrived(String topic, MqttMessage msgStr) throws Exception {try {String enCodeMsg = new String(msgStr.getPayload());Logger.d("==收到消息: " + enCodeMsg);if (enCodeMsg.contains("请求视频推流")) {initLiveCamera();} else if (enCodeMsg.contains("退出视频推流")) {deStroyLive();}//收到消息,这里弹出Toast表示。如果需要更新UI,可以使用广播或者EventBus进行发送//收到其他客户端的消息后,响应给对方告知消息已到达或者消息有问题等
//                response("message arrived");} catch (Exception e) {e.printStackTrace();}}@Overridepublic void deliveryComplete(IMqttDeliveryToken arg0) {}@Overridepublic void connectionLost(Throwable arg0) {Logger.d("==连接断开 ");
//            doClientConnection();//连接断开,重连}};public static void disconnect(Context context) {try {if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) {mqttAndroidClient.unsubscribe(PUBLISH_TOPIC);mqttAndroidClient.unregisterResources();mqttAndroidClient.disconnect(0); //断开连接mqttAndroidClient = null;context.stopService(new Intent(context, XyMqttService.class));ZegoExpressEngine.destroyEngine(new IZegoDestroyCompletionCallback() {@Overridepublic void onDestroyCompletion() {//销毁成功}});}} catch (Exception e) {e.printStackTrace();}}/*** 单向* 认证*/public static SSLSocketFactory getSingleSocketFactory(InputStream caCrtFileInputStream) throws Exception {Security.addProvider(new BouncyCastleProvider());X509Certificate caCert = null;BufferedInputStream bis = new BufferedInputStream(caCrtFileInputStream);CertificateFactory cf = CertificateFactory.getInstance("X.509");while (bis.available() > 0) {caCert = (X509Certificate) cf.generateCertificate(bis);}KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());caKs.load(null, null);caKs.setCertificateEntry("cert-certificate", caCert);TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());tmf.init(caKs);SSLContext sslContext = SSLContext.getInstance("TLSv1.2");sslContext.init(null, tmf.getTrustManagers(), null);return sslContext.getSocketFactory();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/220032.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【设计模式--行为型--命令模式】

设计模式--行为型--命令模式 命令模式定义结构案例优缺点使用场景 命令模式 定义 将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行存储,传递,调用…

Springboot整合Redis实现消息发布订阅

一、前言 有时候在实际项目中,某些业务场景下我们需要使用消息的发布订阅功能,以实现某些特殊的需求,那么我们实际上可以有多种选择,比如使用常见的消息中间件Rabbitmq,Kafka,Activemq等,但这几…

Nodejs 第二十四章(zlib)

在 Node.js 中,zlib 模块提供了对数据压缩和解压缩的功能,以便在应用程序中减少数据的传输大小和提高性能。该模块支持多种压缩算法,包括 Deflate、Gzip 和 Raw Deflate。 zlib 模块的主要作用如下: 数据压缩:使用 z…

07--面向对象OOP--02

学习面向对象内容的三条主线 Java类及类的成员:(重点)属性、方法、构造器;(熟悉)代码块、内部类面向对象的特征:封装、继承、多态、(抽象)其他关键字的使用:…

城轨线路列车时刻表与车站客流控制协同优化方法

文章信息 论文题目为《城轨线路列车时刻表与车站客流控制协同优化方法》,该文于2021年发表于《交通运输系统工程与信息》上。文章考虑换入客流影响下列车时刻表与客流控制的协同优化问题,以最小化乘车延误人数为目标,以列车时刻表、客流控制和…

前端成神之路-CSS基础选择器

前端成神之路-CSS基础选择器 目录 前端成神之路-CSS基础选择器 CSS选择器(重点) 1. CSS选择器作用(重点) 选择器的作用 2. CSS基础选择器 2.1 标签选择器 2.2 类选择器 2.3 类选择器特殊用法- 多类名 2.4 id选择器 id选…

java代码编写twitter授权登录

在上一篇内容已经介绍了怎么申请twitter开放的API接口。 下面介绍怎么通过twitter提供的API,进行授权登录功能。 开发者页面设置 首先在开发者页面开启“用户认证设置”,点击edit进行信息编辑。 我的授权登录是个网页,并且只需要进行简单的…

动物姿态估计:微调 YOLOv8 姿态模型

动物姿态估计是计算机视觉的一个研究领域,是人工智能的一个子领域,专注于自动检测和分析图像或视频片段中动物的姿势和位置。目标是确定一种或多种动物的身体部位(例如头部、四肢和尾巴)的空间排列。这项技术具有广泛的应用&#…

目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】边缘检测(附MATLAB代码实现)

目录 前言 知识储备 数字图像处理(Digital Image Processing) 数字图像处理基础知识与算法

子组件调用父组件的方法

在React中使用函数组件(也称为无状态组件)和Hooks时,你可以通过以下方式让子组件调用父组件的方法: 1. 使用回调函数(Callback Function) 这是最常见的方法。当子组件需要调用父组件的方法时,…

uniapp 单选按钮 选中默认设备

需求1:选中默认设备,113 和114 和139都可以选中一个默认设备 选中多个默认设备方法: async toSwitch(typeItem, title) {const res await this.setDefaultDev(typeItem.ibdr_devsn, typeItem.ibdr_pid)if (!res) {this.common.toast(切换默…

关于在Java中打印三角形图形的汇总

前面写过一些关于打印三角形图形代码的文章,这里进行了汇总,话不多说,直接上代码: /*** 关于打印三角形的汇总*/ public class Work1 {public static void main(String[] args) {int num 5;/** 打印如下图形:* ** …

OPCServer KEPServer安装和使用

OPCServer KEPServer安装和使用 简介 KEPServer软件是免费的,驱动收费,每天2小时试用时间, 免费用来模拟仿真是很不错的选择 OPC DA 和OPC UA都支持 中文官网地址: https://www.kepware.com/zh-cn/ 中文官方文档(经常有更新,其…

分库分表及ShardingShpere-proxy数据分片

为什么需要分库? 随着数据量的急速上升,单个数据库可能会QPS过高导致读写耗时过长而出现性能瓶颈,所以需要考虑拆分数据库,将数据库分布在不同实例上提升数据库可用性。主要的原因有如下: 磁盘存储。业务量剧增&…

Vite + React + tailwindcss + ts + 多Nodejs环境... 速搭

最近接触了前端代码,作为一个后端,能将其搭起来并用于生产,我感到很是欣慰。 本文纯安装速记与关键点记录,适合有一定经验且对前端React及生态有一些小了解,想要快速的将一个框架搭建起来的童鞋。可当成一个指引。 N…

华为OD机试 - 高效货运(Java JS Python C)

题目描述 老李是货运公司承运人,老李的货车额定载货重量为 wt。 现有两种货物: 货物 A 单件重量为 wa,单件运费利润为 pa货物 B 单件重量为 wb,单件运费利润为 pb老李每次发车时载货总重量刚好为货车额定的载货重量 wt,车上必须同时有货物 A 和货物 B ,货物A、B不可切割…

javaWebssh汽车销售管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh汽车销售管理系统是一套完善的web设计系统(系统采用ssh框架进行设计开发),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用 B/S模式开发。开发环境为TOMCAT7.…

redis-学习笔记(Jedis zset 简单命令)

zadd & zrange zadd , 插入的第一个参数是 zset , 第二个参数是 score, 第三个参数是 member 成员 内部依据 score 排序 zrange 返回 key 对应的 对应区间内的值 zrangeWithScore 返回 key 对应的 对应区间内的值和分数 示例代码 zcard 返回 key 对应的 zset 的长度 示例代…

05-命令模式

意图(GOF定义) 将一个请求封装为一个对象,从而使你可用不同的请求对客户端进行参数化,对请求排队或者记录日志,以及可支持撤销的操作。 理解 命令模式就是把一些常用的但比较繁杂的工作归类为成一组一组的动作&…

旅游管理虚拟情景实训教学系统演示

首先,虚拟情景实训教学系统为旅游管理专业的学生提供了一个全新的实践平台。在传统的旅游管理教学中,学生往往只能通过理论学习来了解相关知识,而无法亲身实践。虚拟情景实训教学系统则可以通过模拟真实的旅游场景,让学生能够亲身…