Android 物联网开发:设备通过 MQTT 协议接入阿里云 IoT

Stella981
• 阅读 1614

Android 物联网开发:设备通过 MQTT 协议接入阿里云 IoT

在全球智能手机市场里,谷歌开发的Android移动操作系统市场占有率已经高达90%。随着物联网智能硬件升级,也逐渐成为智能摄像头,智能对讲门禁,人脸识别闸机,智能电视,智能广告屏等 IoT 设备的首选操作系统。

《物联网开发实战》本期为大家详细讲解 Android 设备通过 MQTT 协议接入阿里云 IoT 物联网平台的完整过程。

目录:

  • 阿里云 IoT 物联网云端开发

  • 使用Android Studio开发设备端程序

  • 联机运行,日志详解

IoT 物联网平台

1.免费开通阿里云 IoT物联网云服务:

https://www.aliyun.com/product/iot-deviceconnect

Android 物联网开发:设备通过 MQTT 协议接入阿里云 IoT

2.创建产品,选择自定义品类,直连设备:

Android 物联网开发:设备通过 MQTT 协议接入阿里云 IoT

3.添加产品功能定义,我们以采集Android设备的硬件厂商、型号、Android版本、SDK版本信息为例:

Android 物联网开发:设备通过 MQTT 协议接入阿里云 IoT

物模型属性通信Topic和Payload如下:

// 属性上报 Topic:/sys/{productKey}/{deviceName}/thing/event/property/post// 属性 Payload:{    "id":123452452,    "version":"1.0",    "params":{        "brand":"HUAWEI",        "model":"ELE-AL00",        "android":"10",        "sdk":29    },    "method":"thing.event.property.post"}

参考文档:

https://help.aliyun.com/document\_detail/89301.html

4.注册设备,此时设备为未激活状态。

Android 物联网开发:设备通过 MQTT 协议接入阿里云 IoT

点击DeviceSecret的查看,获取身份三元组。

Android 物联网开发:设备通过 MQTT 协议接入阿里云 IoT

Android 设备开发

5.Android应用程序依赖

Gradle 配置:

repositories {        maven {            url "https://repo.eclipse.org/content/repositories/paho-releases/"        }}dependencies {    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.2'    implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'}

MANIFEST 配置:

<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.WAKE_LOCK" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><application>  <!-- Mqtt Service -->    <service android:name="org.eclipse.paho.android.service.MqttService" /></application>

6.设备三元组生成MQTT 的CONNECT参数转换工具

import javax.crypto.Mac;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import java.util.Arrays;import java.util.Map;/** * AliyunIoTSignUtil */public class AliyunIoTSignUtil {    public static String sign(Map<String, String> params, String deviceSecret, String signMethod) {        //将参数Key按字典顺序排序        String[] sortedKeys = params.keySet().toArray(new String[] {});        Arrays.sort(sortedKeys);        //生成规范化请求字符串        StringBuilder canonicalizedQueryString = new StringBuilder();        for (String key : sortedKeys) {            if ("sign".equalsIgnoreCase(key)) {                continue;            }            canonicalizedQueryString.append(key).append(params.get(key));        }        try {            String key = deviceSecret;            return encryptHMAC(signMethod,canonicalizedQueryString.toString(), key);        } catch (Exception e) {            throw new RuntimeException(e);        }    }    /**     * HMACSHA1加密     *     */    public static String encryptHMAC(String signMethod,String content, String key) throws Exception {        SecretKey secretKey = new SecretKeySpec(key.getBytes("utf-8"), signMethod);        Mac mac = Mac.getInstance(secretKey.getAlgorithm());        mac.init(secretKey);        byte[] data = mac.doFinal(content.getBytes("utf-8"));        return bytesToHexString(data);    }    public static final String bytesToHexString(byte[] bArray) {        StringBuffer sb = new StringBuffer(bArray.length);        String sTemp;        for (int i = 0; i < bArray.length; i++) {            sTemp = Integer.toHexString(0xFF & bArray[i]);            if (sTemp.length() < 2) {                sb.append(0);            }            sb.append(sTemp.toUpperCase());        }        return sb.toString();    }}

7.设备发起建立 MQTT 连接

public void connectMqtt(String url, String clientId, String mqttUsername, String mqttPassword) throws Exception {        mqttAndroidClient = new MqttAndroidClient(getApplicationContext(), url, clientId);        MqttConnectOptions connOpts = new MqttConnectOptions();        // MQTT 3.1.1        connOpts.setMqttVersion(4);        connOpts.setAutomaticReconnect(true);        connOpts.setCleanSession(true);        connOpts.setUserName(mqttUsername);        connOpts.setPassword(mqttPassword.toCharArray());        connOpts.setKeepAliveInterval(60);        mqttAndroidClient.setCallback(new MqttCallbackExtended() {            @Override            public void connectComplete(boolean reconnect, String serverURI) {                postTopic();            }            @Override            public void connectionLost(Throwable cause) {                Log.d(TAG, "connectionLost " + cause.getMessage());            }            @Override            public void messageArrived(String topic, MqttMessage message) throws Exception {                Log.d(TAG, "messageArrived topic=" + topic+", message=" + new String(message.getPayload()));                //此处为收到的云端数据            }            @Override            public void deliveryComplete(IMqttDeliveryToken token) {                Log.d(TAG, "deliveryComplete token=" + token.toString());            }        });        mqttAndroidClient.connect(connOpts,null,                new IMqttActionListener(){                    @Override                    public void onSuccess(IMqttToken asyncActionToken) {                        Log.d(TAG, "connect 回调 连接成功");                    }                    @Override                    public void onFailure(IMqttToken asyncActionToken, Throwable exception) {                        Log.d(TAG, "connect 回调 onFailure,原因 exception=" + exception.toString());                    }                });    }

8.设备上报物模型属性信息

public void postTopic(){     JSONObject params = new JSONObject();    params.put("brand",Build.BRAND);    params.put("model",Build.MODEL);    params.put("android",Build.VERSION.RELEASE);    params.put("sdk",Build.VERSION.SDK_INT);    JSONObject payload = new JSONObject();    payload.put("id",System.currentTimeMillis());    payload.put("version","1.0");    payload.put("params",params);    payload.put("method","thing.event.property.post");    MqttMessage message = new MqttMessage();    message.setPayload(payload.toString().getBytes("utf-8"));    message.setQos(0);    mqttAndroidClient.publish(postTopic, message);}

联机运行

9.编译并部署程序到手机

Android 物联网开发:设备通过 MQTT 协议接入阿里云 IoT

10.查看设备详情,状态变为在线,物模型数据可以查看到Android设备的信息

Android 物联网开发:设备通过 MQTT 协议接入阿里云 IoT

11.日志服务查看属性上报完整日志:

Android 物联网开发:设备通过 MQTT 协议接入阿里云 IoT

通过观察日志,我们了解到物模型属性上报包含三个步骤:

  1. 设备publish数据到IoT平台

  2. IoT物联网平台按照预先定义的物模型校验并存储数据

  3. IoT物联网平台给设备响应物模型属性reply消息

完整源码获取方式:

本文分享自微信公众号 - IoT物联网技术(IoT-Tech-Expo)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这