Android之MQTT的使用

MQTT的简单介绍

MQTT是广泛应用于物联网的传输协议,基于TCP

MQTT有一个代理服务器,其客户端可以订阅主题或向一个主题发送消息,从而实现通信

MQTT 设计了 3 个 QoS 等级。

  • QoS 0:消息最多传递一次,如果当时客户端不可用,则会丢失该消息。
  • QoS 1:消息传递至少 1 次。
  • QoS 2:消息仅传送一次。

MQTT依赖

在Android中使用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 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'

但是,这些依赖只支持SDK31(Android 11)及以下的系统,因此我们需要修改:

android{
    ...
    compileSdk 31

    defaultConfig{
        ...
        targetSdk 31
        ...
    }
}

另外,高版本的core-ktx依赖不支持33及以下的SDK,因此我们需要修改它的依赖:

implementation 'androidx.core:core-ktx:1.0.0'

而且,这些MQTT的依赖不支持AndroidX,因此需要在gradle.properties下增加以下配置:

android.enableJetifier=true

我们也可以使用国内镜像源加速构建,新版本的Android studio需要在settings.gradle修改配置:

pluginManagement {
    repositories {
        maven { url 'https://maven.aliyun.com/repository/central' }
        maven { url 'https://maven.aliyun.com/repository/jcenter' }
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
        maven { url 'https://maven.aliyun.com/repository/public' }
        maven { url 'https://repo.huaweicloud.com/repository/maven' }
        maven { allowInsecureProtocol = true
            url 'http://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
        maven { url "https://jitpack.io" }
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        maven { url 'https://maven.aliyun.com/repository/central' }
        maven { url 'https://maven.aliyun.com/repository/jcenter' }
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
        maven { url 'https://maven.aliyun.com/repository/public' }
        maven { url 'https://repo.huaweicloud.com/repository/maven' }
        maven { allowInsecureProtocol = true
            url 'http://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
        maven { url "https://jitpack.io" }
    }
}

当然,我们需要申请权限并注册服务:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <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 android:name="org.eclipse.paho.android.service.MqttService" />

        ...

MQTT的基本使用

要使用MQTT,需要先创建一个MQTT客户端对象:

val url = "tcp://192.168.1.11:1883"
val clientId = "app"
val mqttClient = MqttAndroidClient(this, url, clientId)

MqttAndroidClient对象创建时接收三个参数,按照顺序,功能如下:

  1. 当前的上下文(this),
  2. 服务器的url,注意使用tcp协议,
  3. 客户端的id,一般应保证其是唯一的

想要连接到服务器,需要配置参数,通过MqttConnectOptions对象:

val option = MqttConnectOptions()
option.userName = "test"
option.password = "123456".toCharArray()

在连接服务器之前,需要设置mqttClient的回调:

mqttClient.setCallback(object :MqttCallback{
    override fun connectionLost(cause: Throwable?) {
        // 连接丢失
    }

    override fun messageArrived(topic: String?, message: MqttMessage?) {
        // 收到信息
    }

    override fun deliveryComplete(token: IMqttDeliveryToken?) {
        // 消息发送完成
    }
})

接下来调用mqttClient.connect方法连接到服务器:

mqttClient.connect(option, null, object :IMqttActionListener{
    override fun onSuccess(asyncActionToken: IMqttToken?) {
        // 成功
    }

    override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
        // 失败
    }
})

connect接收三个参数,按照顺序,功能如下:

  1. 配置参数(刚刚创建的)
  2. 一个上下文,用于将上下文传递给回调,如不需要则设置为null
  3. 一个IMqttActionListener,回调

注意,只有订阅后的主题才能被接收,我们需要在connect的回调下订阅主题,或确保已经连接成功后再订阅主题,采用mqttClient的subscribe方法:

mqttClient.connect(option, null, object :IMqttActionListener{
    override fun onSuccess(asyncActionToken: IMqttToken?) {
        mqttClient.subscribe("Topic", 0)
    }

    ...
})

subscribe方法接收两个参数,第一个参数是主题的名称,第二个参数是Qos

要发送消息,可以通过publish方法,同样需要在connect的回调下发送消息,或确保已经连接成功后再发送消息

mqttClient.publish("Topic", MqttMessage("Hello World".toByteArray()))

publish接收两个参数,第一个参数是主题的名称,第二个参数是MqttMessage对象

完整代码如下:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val url = "tcp://192.168.1.11:1883"
        val clientId = "app"
        val mqttClient = MqttAndroidClient(this, url, clientId)
        val option = MqttConnectOptions()
        option.userName = "test"
        option.password = "123456".toCharArray()
        mqttClient.setCallback(object :MqttCallback{
            override fun connectionLost(cause: Throwable?) {
                // 连接丢失
                cause?.printStackTrace()
            }

            override fun messageArrived(topic: String?, message: MqttMessage?) {
                Log.d("message", "messageArrived: $message")
            }

            override fun deliveryComplete(token: IMqttDeliveryToken?) {
                // 消息发送完成
            }
        })
        mqttClient.connect(option, null, object :IMqttActionListener{
            override fun onSuccess(asyncActionToken: IMqttToken?) {
                mqttClient.subscribe("Topic", 0)
                mqttClient.publish("Topic", MqttMessage("Hello World".toByteArray()))
            }

            override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
                // 失败
                exception?.printStackTrace()
            }
        })
    }
}

使用MQTT的测试工具订阅主题Topic,收到消息:

使用MQTT的测试工具向主题"Topic"发送Hello Android,控制台输出:

D/message: messageArrived: Hello Android

可以看到,我们成功地使用了MQTT

  • 21
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值