Android之MQTT的使用

news2024/9/25 9:32:17

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

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

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

相关文章

Jmeter基础使用---Token鉴权接口关联

接口测试流程&#xff1a; 查看API接口文档&#xff0c;熟悉接口业务&#xff08;地址、端口、参数、鉴权、状态码&#xff09;设计接口测试用例&#xff08;正例&#xff1a;正确的结果&#xff1b;反例&#xff1a;鉴权异常、参数异常、兼容异常、其他异常&#xff09;使用接…

Java中的List

List集合的特有方法 方法介绍 方法名描述void add(int index,E element)在此集合中的指定位置插入指定的元素E remove(int index)删除指定索引处的元素&#xff0c;返回被删除的元素E set(int index,E element)修改指定索引处的元素&#xff0c;返回被修改的元素E get(int inde…

rtt的io设备框架面向对象学习-io设备管理层

目录 1.设备基类2.rtt基类2.1 rtt基类定义2.2 对象容器定义2.3 rtt基类构造函数 3.io设备管理接口4.总结 这层我的理解就是rtt基类和设备基类所在&#xff0c;所以抽离出来好点&#xff0c;不然每个设备类都要重复它。 1.设备基类 /include/rtdef.h中定义了设备基类struct rt_…

Spring:EnclosingClass工具类分辨

Spring&#xff1a;EnclosingClass工具类分辨 1 前言 通过Spring的工具分辨EnclosingClass类。 测试类如下&#xff1a; package com.xiaoxu.test.enclosingClass;/*** author xiaoxu* date 2024-01-18* java_demo2:com.xiaoxu.test.enclosingClass.Outter*/ public class …

计算机专业必看的几部电影推荐

计算机专业必看的几部电影&#xff0c;就像一场精彩的编程盛宴&#xff01;《黑客帝国》让你穿越虚拟世界&#xff0c;感受高科技的魅力&#xff1b;《社交网络》揭示了互联网巨头的创业之路&#xff0c;《源代码》带你穿越时间解救世界&#xff0c;这些电影不仅带我们穿越到科…

模型部署 - onnx 的导出和分析 -(1) - PyTorch 导出 ONNX - 学习记录

onnx 的导出和分析 一、PyTorch 导出 ONNX 的方法1.1、一个简单的例子 -- 将线性模型转成 onnx1.2、导出多个输出头的模型1.3、导出含有动态维度的模型 二、pytorch 导出 onnx 不成功的时候如何解决2.1、修改 opset 的版本2.2、替换 pytorch 中的算子组合2.3、在 pytorch 登记&…

SpringBoot+Maven多环境配置模式

我这里有两个配置文件 然后在最外层的父级POM文件里面把这个两个配置文件写上 <profiles><profile><id>druid</id><properties><spring.profiles.active>druid</spring.profiles.active></properties><activation><…

管理系统提升:列表页构成要素,拒绝千篇一律

大家伙&#xff0c;我是大千UI工场&#xff0c;专注UI知识案例分享和接单&#xff0c;本期带来B端系统列表页的分享&#xff0c;欢迎大家关注、互动交流。 一、什么是列表页 管理系统列表页是指管理系统中用于展示和管理数据的页面&#xff0c;通常以表格或列表的形式呈现。列…

经典语义分割(一)利用pytorch复现全卷积神经网络FCN

经典语义分割(一)利用pytorch复现全卷积神经网络FCN 这里选择B站up主[霹雳吧啦Wz]根据pytorch官方torchvision模块中实现的FCN源码。 Github连接&#xff1a;FCN源码 1 FCN模型搭建 1.1 FCN网络图 pytorch官方实现的FCN网络图&#xff0c;如下所示。 1.2 backbone FCN原…

斐波那契数列模型---使用最小花费爬楼梯

746. 使用最小花费爬楼梯 - 力扣&#xff08;LeetCode&#xff09; 1、状态表示&#xff1a; 题目意思即&#xff1a;cost[i]代表从第i层向上爬1阶或者2阶&#xff0c;需要花费多少力气。如cost[0]&#xff0c;代表从第0阶爬到第1阶或者第2阶需要cost[0]的力气。 一共有cost.…

Java - List集合与Array数组的相互转换

一、List 转 Array 使用集合转数组的方法&#xff0c;必须使用集合的 toArray(T[] array)&#xff0c;传入的是类型完全一样的数组&#xff0c;大小就是 list.size() public static void main(String[] args) throws Exception {List<String> list new ArrayList<S…

梯度下降算法(带你 原理 实践)

目录 一、引言 二、梯度下降算法的原理 三、梯度下降算法的实现 四、梯度下降算法的优缺点 优点&#xff1a; 缺点&#xff1a; 五、梯度下降算法的改进策略 1 随机梯度下降&#xff08;Stochastic Gradient Descent, SGD&#xff09; 2 批量梯度下降&#xff08;Batch…

【解读】工信部数据安全能力提升实施方案

近日&#xff0c;工信部印发《工业领域数据安全能力提升实施方案&#xff08;2024-2026年&#xff09;》&#xff0c;提出到2026年底&#xff0c;我国工业领域数据安全保障体系基本建立&#xff0c;基本实现各工业行业规上企业数据安全要求宣贯全覆盖。数据安全保护意识普遍提高…

vue api封装

api封装 由于一个项目里api是很多的&#xff0c;随处都在调&#xff0c;如果按照之前的写法&#xff0c;在每个组件中去调api&#xff0c;一旦api有改动&#xff0c;遍地都要去改&#xff0c;所以api应该也要封装一下&#xff0c;将api的调用封装在函数中&#xff0c;将函数集…

sql 行列互换

在SQL中进行行列互换可以使用PIVOT函数。下面是一个示例查询及其对应的结果&#xff1a; 创建测试表格 CREATE TABLE test_table (id INT PRIMARY KEY,name VARCHAR(50),category VARCHAR(50) );向测试表格插入数据 INSERT INTO test_table VALUES (1, A, Category A); INSE…

Go语言必知必会100问题-15 缺少代码文档

缺少代码文档 文档&#xff08;代码注释&#xff09;是编码的一个重要方面&#xff0c;它可以降低客户端使用API的复杂度&#xff0c;也有助于项目维护。在Go语言中&#xff0c;我们应该遵循一些规则使得我们的代码更地道。下面一起来看看这些规则。 每个可导出的元素必须添加…

YOLOv9有效提点|加入MobileViT 、SK 、Double Attention Networks、CoTAttention等几十种注意力机制(五)

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、本文介绍 本文只有代码及注意力模块简介&#xff0c;YOLOv9中的添加教程&#xff1a;可以看这篇文章。 YOLOv9有效提点|加入SE、CBAM、ECA、SimA…

JVM相关问题

JVM相关问题 一、Java继承时父子类的初始化顺序是怎样的&#xff1f;二、JVM类加载的双亲委派模型&#xff1f;三、JDK为什么要设计双亲委派模型&#xff0c;有什么好处&#xff1f;四、可以打破JVM双亲委派模型吗&#xff1f;如何打破JVM双亲委派模型&#xff1f;五、什么是内…

【数据结构】前缀树的模拟实现

目录 1、什么是前缀树&#xff1f; 2、模拟实现 2.1、前缀树节点结构 2.2、字符串的添加 2.3、字符串的查寻 2.3.1、查询树中有多少个以字符串"pre"作为前缀的字符串 2.3.2、查询某个字符串被添加过多少次 2.4、字符串的删除 3、完整代码 1、什么是前缀树&…

(资源篇)2025届暑假实习春招全攻略路线

绝对的全攻略&#xff0c;资源完善程度绝对的全网唯一。 觉得有帮助的&#xff1a;随手一键三连关注就是对up主最大的激励。 绝对的宝藏up主&#xff01;&#xff01;&#xff01;&#xff0c;up主每天都会进行更新视频&#xff0c;算法视频or校招信息or八股讲解。 【暴躁老…