需求
Android APP 通过蓝牙读取工业设备上的运行数据,然后通过 MQTT 协议上传到服务器端,再由服务器转发给客户的云平台。
- 客户端是一个华为鸿蒙系统平板。非纯血鸿蒙版本,还能跑 Android Kotlin 开发 App。
- 服务器端使用的是开源的 EMQX 的 MQTT broker。
支持 MQTT 的三方库
最终使用的是
https://github.com/hannesa2/paho.mqtt.android
这个是在一个已经废弃的库
https://github.com/eclipse/paho.mqtt.android
的基础上继续维护的一个项目。因为 eclipse 这个库已经不维护了,不支持最新的 Android 版本。
具体原因参考:
- https://github.com/eclipse/paho.mqtt.android/issues/500
- https://github.com/eclipse/paho.mqtt.android/issues/493
由于第一个库可用,就没有继续测试 HiveMQ MQTT Client 的方案。从 github 上看,好多开发者用的是 HiveMQ 这个库,而且也支持 EMQX。
EMQX 的官方文档
EMQX 官方有个文章,是介绍关于如何在 Android 上连接 EMQX MQTT 服务的。
https://www.emqx.com/zh/blog/android-connects-mqtt-using-kotlin
但是文章是 2020 年写的,不知道现在还能使用么?我测试了一下,只需要将废弃的 eclipse/paho.mqtt.android 替换成 hannesa2/paho.mqtt.android 即可。
注意:一定要参考这个中文的介绍,这篇文章有个对应的英文版,那个内容不全。
如果继续使用废弃的那个库,会遇到各类异常报错:
java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/content/LocalBroadcastManager
java.lang.SecurityException: Caller com.sunzhongwei.mqtt needs to hold android.permission.SCHEDULE_EXACT_ALARM to set exact alarms.
改不完的问题。
跟文档不同的地方
hannesa2/paho.mqtt.android 这个库文档太少,还是尝试了一下才调试成功。
settings.gradle 中添加仓库:
maven { url 'https://jitpack.io' }
build.gradle 中添加依赖:
implementation 'com.github.hannesa2:paho.mqtt.android:4.2.4'
这里只需要一个依赖,而是那个废弃项目还需要额外的 Android Service 服务依赖。
AndroidManifest.xml 中添加:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
也是不再需要添加 application service。
Dependency 'androidx.work:work-runtime-ktx:2.9.0' requires libraries and applications that depend on it to compile against version 34 or later of the Android APIs. :app is currently compiled against android-33.
需要将 sdk 从 33 升级到 34:
- compileSdk 34
- targetSdk 34
其他代码部分,按照文档中的即可,不需要额外的修改。
publish 消息测试
mqttClient.connect(options, null, object : IMqttActionListener {
override fun onSuccess(asyncActionToken: IMqttToken?) {
Log.d(MQTT_TAG, "Connection success")
publish("hello/world", "hello gaga", 0) // 发送消息
}
override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
Log.d(MQTT_TAG, "Connection failure")
}
})
在 EMQX 后台就能看到对应的消息了
心跳测试
从 EMQX 的网页后台看看,建立的 MQTT 连接默认心跳间隔为 60 秒。
将 App 切回系统桌面,或者锁屏。从后台看,连接也是一直保持的,说明后台有个定时任务在自动保持心跳。
只有将 Android 的 Wifi 禁用之后,过一分钟后才会显示 MQTT 连接断开。
默认不会自动重连。需要配置连接参数:
options.isAutomaticReconnect = true
然后就可以自动重试重新连接了。
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式