Android集成MQTT客户端实践
liebian365 2025-01-12 16:19 17 浏览 0 评论
现在物联网越来越深入我们的生活了,随处可见的穿戴设备、传感器,无时无刻不在采集着我们的信息。比如智能手环,我们运动的步数、心率等数据被小小的传感器时刻记录着。
一般来说,这些数据可以直接通过蓝牙等协议传输,但也有不少是通过其他途径,比如MQTT,设备采集的数据直接上传到云端的MQTT服务器上,而其他的终端如手机app则通过订阅获取数据,进行展示及数据分析等。
今天我们就来看看一个Android程序该如何集成MQTT client来与设备进行数据交互。
集成
首先引入依赖
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 "androidx.localbroadcastmanager:localbroadcastmanager:1.0.0"
注意这里引入了"androidx.localbroadcastmanager",是因为我们项目使用了androidx,项目编译时报了"support.v4"包找不到的错误,而androidx中又不能直接引入"support.v4",网上找了一圈发现了这个靠谱的方法。当然,这还不够,还要在gradle.properties中增加下面一个配置项
android.enableJetifier=true
接下来要在AndroidManifest.xml中声明MqttService,如下
<service android:name="org.eclipse.paho.android.service.MqttService" />
这样mqtt的基本集成就算完成了。
使用
以下示例代码使用Kotlin语言,不过大家应该都能看懂。
首先我们需要一些配置项来接入MQTT服务器,多说一句,这个mqtt server可以直接用开源的自己部署,也可以直接买云厂商提供的。我们客户端集成需要的配置项如下
class Config {
companion object {
const val serverUri = "xxx"
const val clientId = "xxx"
const val instanceId = "xxx"
const val accessKey = "xxx"
const val secretKey = "xxx"
}
}
这里歪哥项目中使用的是阿里云的mqtt server,所以接入配置像上面这样,其他的可能稍有不同,具体看官方给的文档就行。
然后就是具体的订阅、发布等操作了
class MqttSimple(var mqttAndroidClient: MqttAndroidClient) {
val topicCommand = "xxx"
val topicData = "xxx"
// 订阅
fun subscribe() {
try {
mqttAndroidClient.setCallback(object : MqttCallbackExtended {
override fun connectComplete(reconnect: Boolean, serverURI: String) {
}
override fun connectionLost(cause: Throwable) {
Log.e("mqtt", "connectionLost", cause)
}
@Throws(Exception::class)
override fun messageArrived(topic: String, message: MqttMessage) {
val body = String(message.payload)
Log.w("mqtt", "messageArrived, topic: $topic, msg: $body")
}
override fun deliveryComplete(token: IMqttDeliveryToken) {}
})
val mqttConnectOptions = MqttConnectOptions()
mqttConnectOptions.isAutomaticReconnect = true
mqttConnectOptions.userName = "Signature|${Config.accessKey}|${Config.instanceId}"
mqttConnectOptions.password =
Tool.macSignature(Config.clientId, Config.secretKey).toCharArray()
mqttAndroidClient.connect(mqttConnectOptions, null, object : IMqttActionListener {
override fun onSuccess(asyncActionToken: IMqttToken) {
Log.w("mqtt", "connect onSuccess")
subscribe(topicData)
}
override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
Log.e("mqtt", "connect onFailure", exception)
}
})
} catch (e: Exception) {
e.printStackTrace()
}
}
// 发布(发送一条指令)
fun sendCommand(cmd: String) {
try {
val mqttConnectOptions = MqttConnectOptions()
mqttConnectOptions.isAutomaticReconnect = true
mqttConnectOptions.userName = "Signature|${Config.accessKey}|${Config.instanceId}"
mqttConnectOptions.password =
Tool.macSignature(Config.clientId, Config.secretKey).toCharArray()
mqttAndroidClient.connect(mqttConnectOptions, null, object : IMqttActionListener {
override fun onSuccess(asyncActionToken: IMqttToken) {
Log.w("mqtt", "connect onSuccess")
publish(cmd, topicCommand)
}
override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
Log.e("mqtt", "connect onFailure", exception)
}
})
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun publish(msg: String, topic: String) {
try {
val message = MqttMessage()
message.payload = msg.toByteArray()
mqttAndroidClient.publish(topic, message, null, object : IMqttActionListener {
override fun onSuccess(asyncActionToken: IMqttToken) {
Log.w("mqtt", "publish success, topic: $topic, msg: $msg")
}
override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
Log.w("mqtt", "publish failed, topic: $topic, msg: $msg")
}
})
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun subscribe(topic: String) {
try {
val topicFilter = arrayOf(topic)
val qos = intArrayOf(1)
mqttAndroidClient.subscribe(topicFilter, qos, null, object : IMqttActionListener {
override fun onSuccess(asyncActionToken: IMqttToken) {
Log.w("mqtt", "subscribe success, topic: $topic")
}
override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
Log.e("mqtt", "subscribe failed", exception)
}
})
} catch (e: Exception) {
e.printStackTrace()
}
}
}
这里有两个topic,topicCommand是数据发送的通道,我们可以以此向设备发动指令,topicData是数据订阅接收的通道。当然,示例中有可以优化的地方,比如不应该每次都重复连接server,大家实际使用时要注意些。
总结
MQTT类似于RocketMQ这种,一般是用做物联网场景的消息传输协议,现在这种物联网数据采集传输的场景还是很多的,特别是跟大模型的结合,已然是热门研究方向,大家还是有必要了解一下的。
- 上一篇:eclipse安装图解
- 下一篇:MQTT协议介绍及Java教程
相关推荐
- 4万多吨豪华游轮遇险 竟是因为这个原因……
-
(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...
- “菜鸟黑客”必用兵器之“渗透测试篇二”
-
"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...
- 科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白
-
作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...
- 麦子陪你做作业(二):KEGG通路数据库的正确打开姿势
-
作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...
- 知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势
-
智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...
- 每日新闻播报(September 14)_每日新闻播报英文
-
AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...
- 香港新巴城巴开放实时到站数据 供科技界研发使用
-
中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...
- 5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper
-
本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...
- Qt动画效果展示_qt显示图片
-
今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...
- 如何从0到1设计实现一门自己的脚本语言
-
作者:dong...
- 三年级语文上册 仿写句子 需要的直接下载打印吧
-
描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...
- C++|那些一看就很简洁、优雅、经典的小代码段
-
目录0等概率随机洗牌:1大小写转换2字符串复制...
- 二年级上册语文必考句子仿写,家长打印,孩子照着练
-
二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)