腾讯IOT 安卓开发初探

目的:将Andorid端作为一个物联网设备(device),然后将其安卓设备上面的数据发送到腾讯云IOT开发平台上。(这里我们将手机上面的GPS经纬度发送到腾讯云IOT平台上)。

腾讯IOT开发平台:https://console.cloud.tencent.com/iotexplorer

腾讯IOT Java SDK GitHub:https://github.com/tencentyun/iot-device-java

开发工具:Android Studio

代码Github:android_test_iot_for_tecent

Tecent IOT 开发平台的使用

开发平台的官方参考文档网址:https://cloud.tencent.com/document/product/1081,不过个人觉得其文档对于Java SDK的描述不够详细,需要去看其 Demo源码才能明白其工作流程。

腾讯云IOT开发平台的项目结构如下所示:分为两层——项目产品。用在使用其平台的时候,既需要创建project,也需要创建product。

我们可以将项目理解为智能家居整个系统,因此在项目中有很多产品,比如说智能空调,智能报警器等等产品。

新建项目

新建项目,项目名称随意就行,创建好项目后,进入项目,然后创建产品。

创建产品

创建产品的选项如下:

  • 设备:因为我们是准备将安卓终端作为一台设备来使用的,因此,我们应该选择”设备“,当然,如果我们是准备将它作为网关,则看着选就行了。
  • 认证方式:认证方式选择密钥认证,这样在代码中间直接写设备的密码就行,比证书稍微方便一点(不过实际上证书方便一点)。
  • 数据协议:使用数据模板即可。

添加自定义功能

物联网设备,之所以叫物联网,是因为大家想把传感器获得的数据放在云端,或者通过云端去控制物联网设备。那么放什么数据,控制什么功能,则需要我们去定义。在腾讯IOT中,可以使用新建功能定义这些功能。

点击进入产品,选择新建功能

自定义功能我们只需要两个功能:

  • 经度:position_x
  • 纬度:position_y

建立经度如下,在功能类型中选择属性,数据类型我们选择浮点型。(经度和纬度的范围都在-180.0 ~180.0 )

同理将纬度配置为position_y,功能类型为属性,数据类型同样为浮点型,范围为-180.0 ~180.0 。

关于功能类型的不同,可以参考下面的表格。

以下来自官方文档

功能元素 功能描述 功能标识符
属性 用于描述设备的实时状态,支持读取和设置,如模式、亮度、开关等。 PropertiesId
事件 用于描述设备运行时的事件,包括告警、信息和故障等三种事件类型,可添加多个输出参数,如环境传感器检测到空气质量很差,空调异常告警等。 EventId
行为 用于描述复杂的业务逻辑,可添加多个调用参数和返回参数,用于让设备执行某项特定的任务,例如,开锁动作需要知道是哪个用户在什么时间开锁,锁的状态如何等。 ActionId

点击下一步,进入设备开发。

设备开发

因为我们使用的是Java SDK进行开发,没有使用模组也没有基于OS开发,因此直接点击下一步。

点击下一步就到了微信小程序配置。

微信小程序配置

腾讯IOT平台相比较于其他平台,有一个很大的特点就是可以很好的支持小程序。也就是说,在开发的阶段,就可以使用小程序去验证设备的功能。并且这个微信小程序不需要自己写样式代码,只需要进行简单的配置,就可以直接从小程序上面看到物联网设备的数据。

因为这里我们使用的数据很简单,只有经度和纬度两个数据,所以随便配置一下面板即可。

面板配置

这里面板类型选择标准面板,然后配置一下模板样式(配置长按钮稍微好看一点),配置完效果图如右边所示。

新建设备

新建设备`的意义:创建一个设备代表启动了一个账号(这个设备会提供一个密钥),我们的设备使用这个密钥,就可以让我们的设备连接腾讯云IOT平台进行数据交互。

新建设备的步骤如下所示:

使用设备

点击test_device,进入设备管理。

设备管理界面如下所示:

  • 设备信息:这里面是设备的一些基本属性,其中通过设备名称设备密钥,和产品ID就可以唯一定位一个设备,然后对其进行操作。

  • 设备日志:设备日志里面保存着设备的上行和下行数据。

  • 在线调试:通过在线调试,我们可以模拟设备的行为,或者对设备下发命令。

,以上的所有就是腾讯IOT平台的介绍,通过上面的操作,就可以创建一个设备,获得其name,key,id,然后对其进行开发了。

安卓开发

安卓开发实现的效果很简单,就是实现一个页面展示经纬度,然后将经纬度数据上传到腾讯IOT平台就行。

前置配置

安卓开发,创建一个Android Studio项目,然后在APP的build gradle 中加入腾讯IOT的SDK

  1. implementation 'com.tencent.iot.explorer:explorer-device-android:3.2.0'

然后新建两个JSON文件(必做!!!!!),data.json ,代表的是设备的属性(这个文件的来源会在后面解释),然后是app-config.json,这个代表的是设备的配置(来源后文解释)。

data.json

data.json 文件一定要放在安卓的assets目录下,安卓如何添加assets目录可以看《Android studio 添加assets文件夹》。data.json需要存放一些数据。这个数据实际上就是自定义功能的数据,复制之后粘贴到data.json文件中。

app-config.json

app-config.json文件的位置一定不要放错,它与src是同级目录,在app的下一级目录。

app-config里面是device的信息,数据内容如下:

  1. {
  2. "PRODUCT_ID": "产品ID",
  3. "DEVICE_NAME": "设备名称",
  4. "DEVICE_PSK": "设备密钥",
  5. "SUB_PRODUCT_ID": "",
  6. "SUB_DEV_NAME": "",
  7. "SUB_DEV_PSK": "",
  8. "SUB_PRODUCT_ID2": "",
  9. "SUB_DEV_NAME2": "",
  10. "SUB_DEV_PSK2": ""
  11. }

来源:

权限配置

位置权限,和联网权限。在AndroidManifest.xml中添加如下权限。值得注意的是,位置权限在安卓版本比较高的设备中,需要使用代码申请位置权限。

  1. <!-- 位置权限-->
  2. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  3. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  4. <!-- 联网权限-->
  5. <uses-permission android:name="android.permission.INTERNET" />

连接平台代码

通过官方提供的SDK,接入腾讯IOT平台实现设备连接和数据上传。代码如下所示,具体的含义写在注释中。在使用中,我们就可以通过实例化IotCloudUtil,然后使用connect()函数来实现连接和propertyReport函数来实现上传数据。

  1. package cc.weno.data_template;
  2. import com.tencent.iot.explorer.device.android.common.Status;
  3. import com.tencent.iot.explorer.device.android.data_template.TXDataTemplateClient;
  4. import com.tencent.iot.explorer.device.android.data_template.TXDataTemplateDownStreamCallBack;
  5. import com.tencent.iot.explorer.device.android.mqtt.TXMqttActionCallBack;
  6. import com.tencent.iot.explorer.device.android.mqtt.TXMqttRequest;
  7. import com.tencent.iot.explorer.device.android.utils.AsymcSslUtils;
  8. import org.eclipse.paho.client.mqttv3.IMqttToken;
  9. import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
  10. import org.eclipse.paho.client.mqttv3.MqttMessage;
  11. import org.json.JSONObject;
  12. import java.util.concurrent.atomic.AtomicInteger;
  13. import cc.weno.location.MainActivity;
  14. /**
  15. * 连接云平台的类
  16. *
  17. * @author XiaoHui
  18. */
  19. public class IotCloudUtil {
  20. /**
  21. * 服务器网址
  22. */
  23. public static String mBrokerURL = "ssl://iotcloud-mqtt.gz.tencentdevices.com:8883";
  24. /**
  25. * 产品ID
  26. */
  27. public static String mProductID = "9JXQQW7SR5";
  28. /**
  29. * 设备名称
  30. */
  31. public static String mDevName = "test_device";
  32. /**
  33. * 设备密钥
  34. */
  35. public static String mDevPSK = "pCIUP7zhTp7snmfxb/72+g==";
  36. /**
  37. * data.json的名字
  38. */
  39. public static String mJsonFileName = "data.json";
  40. /**
  41. * MQTTAction的回调
  42. */
  43. private TXMqttActionCallBack mMqttActionCallBack = null;
  44. /**
  45. * 下行消息的回调
  46. */
  47. private TXDataTemplateDownStreamCallBack mDownStreamCallBack = null;
  48. /**
  49. * MQTT连接实例
  50. */
  51. private TXDataTemplateClient mMqttConnection;
  52. /**
  53. * Activity实例
  54. */
  55. private MainActivity context;
  56. /**
  57. * 请求ID
  58. */
  59. private static AtomicInteger requestID = new AtomicInteger(199);
  60. public IotCloudUtil(MainActivity context) {
  61. this.context = context;
  62. mDownStreamCallBack = new MyDownCallback();
  63. mMqttActionCallBack = new MyMQttCallBack();
  64. }
  65. /**
  66. * 建立MQTT连接
  67. */
  68. public void connect() {
  69. // 创建连接client
  70. mMqttConnection = new TXDataTemplateClient(context, mBrokerURL, mProductID, mDevName, mDevPSK,
  71. null, null, mMqttActionCallBack,
  72. mJsonFileName, mDownStreamCallBack);
  73. // 设置连接参数
  74. MqttConnectOptions options = new MqttConnectOptions();
  75. // 连接超时
  76. options.setConnectionTimeout(8);
  77. // 保持活跃的时间间隔
  78. options.setKeepAliveInterval(240);
  79. // 是否自动重连
  80. options.setAutomaticReconnect(true);
  81. // 因为我们是使用密钥登录,所以需要设置这个
  82. options.setSocketFactory(AsymcSslUtils.getSocketFactory());
  83. // 建立Request请求
  84. TXMqttRequest mqttRequest = new TXMqttRequest("connect", requestID.getAndIncrement());
  85. // 建立连接
  86. mMqttConnection.connect(options, mqttRequest);
  87. }
  88. /**
  89. * 断开MQTT连接
  90. */
  91. public void disconnect() {
  92. TXMqttRequest mqttRequest = new TXMqttRequest("disconnect", requestID.getAndIncrement());
  93. mMqttConnection.disConnect(mqttRequest);
  94. }
  95. /**
  96. * 发送消息
  97. *
  98. * @param property 消息内容
  99. * @param metadata 属性的metadata,目前只包含各个属性对应的时间戳,可以为NULL
  100. * @return 状态
  101. */
  102. public Status propertyReport(JSONObject property, JSONObject metadata) {
  103. return mMqttConnection.propertyReport(property, metadata);
  104. }
  105. /**
  106. * MQTT的回调函数,暂时不考虑
  107. */
  108. public static class MyMQttCallBack extends TXMqttActionCallBack {
  109. @Override
  110. public void onConnectCompleted(Status status, boolean reconnect, Object userContext, String msg) {
  111. }
  112. @Override
  113. public void onConnectionLost(Throwable cause) {
  114. }
  115. @Override
  116. public void onDisconnectCompleted(Status status, Object userContext, String msg) {
  117. }
  118. @Override
  119. public void onPublishCompleted(Status status, IMqttToken token, Object userContext, String errMsg) {
  120. }
  121. @Override
  122. public void onSubscribeCompleted(Status status, IMqttToken asyncActionToken, Object userContext, String errMsg) {
  123. }
  124. @Override
  125. public void onMessageReceived(final String topic, final MqttMessage message) {
  126. }
  127. }
  128. /**
  129. * 实现下行消息处理的回调接口,暂时不考虑
  130. */
  131. private static class MyDownCallback extends TXDataTemplateDownStreamCallBack {
  132. @Override
  133. public void onReplyCallBack(String msg) {
  134. }
  135. @Override
  136. public void onGetStatusReplyCallBack(JSONObject data) {
  137. }
  138. @Override
  139. public JSONObject onControlCallBack(JSONObject msg) {
  140. return null;
  141. }
  142. @Override
  143. public JSONObject onActionCallBack(String actionId, JSONObject params) {
  144. return null;
  145. }
  146. }
  147. }

安卓页面配置

安卓页面很简单,就是展示经度和纬度的数据。

页面代码如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. tools:context=".MainActivity">
  7. <TextView
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:layout_marginLeft="20dp"
  11. android:text="x轴:" />
  12. <TextView
  13. android:id="@+id/x_position"
  14. android:layout_width="wrap_content"
  15. android:layout_height="wrap_content"
  16. android:layout_marginLeft="100dp"
  17. android:text="0.00" />
  18. <TextView
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:layout_marginLeft="20dp"
  22. android:layout_marginTop="100dp"
  23. android:text="y轴:" />
  24. <TextView
  25. android:id="@+id/y_position"
  26. android:layout_width="wrap_content"
  27. android:layout_height="wrap_content"
  28. android:layout_marginLeft="100dp"
  29. android:layout_marginTop="100dp"
  30. android:text="0.00" />
  31. </RelativeLayout>

Activity代码

在MainActivity,我们要实现如下的功能,申请位置权限,获得经纬度的数据,然后进行页面展示,最后将数据上传到云平台。

  1. package cc.weno.location;
  2. import android.Manifest;
  3. import android.location.Location;
  4. import android.os.Bundle;
  5. import android.widget.TextView;
  6. import androidx.appcompat.app.AppCompatActivity;
  7. import androidx.core.app.ActivityCompat;
  8. import com.tencent.iot.explorer.device.android.common.Status;
  9. import org.json.JSONException;
  10. import org.json.JSONObject;
  11. import cc.weno.data_template.IotCloudUtil;
  12. /**
  13. * 主页面,进行展示以及发送数据
  14. *
  15. * @author XiaoHui
  16. */
  17. public class MainActivity extends AppCompatActivity {
  18. /**
  19. * 展示经度
  20. */
  21. private TextView xPositionView;
  22. /**
  23. * 展示纬度
  24. */
  25. private TextView yPositionView;
  26. @Override
  27. protected void onCreate(Bundle savedInstanceState) {
  28. super.onCreate(savedInstanceState);
  29. setContentView(R.layout.activity_main);
  30. xPositionView = findViewById(R.id.x_position);
  31. yPositionView = findViewById(R.id.y_position);
  32. // 基本上现在的安卓机都需要申请位置权限了
  33. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
  34. // 获得位置数据并且发送数据到云平台
  35. getAndSendLocation();
  36. }
  37. private void getAndSendLocation() {
  38. // 获得GPS工具类
  39. GPSUtils gpsUtil = GPSUtils.getInstance(this);
  40. // 获得位置
  41. Location location = gpsUtil.getLocation();
  42. double positionX = location.getLatitude();
  43. double positionY = location.getLongitude();
  44. // 在手机页面上展示
  45. xPositionView.setText(String.valueOf(positionX));
  46. yPositionView.setText(String.valueOf(positionY));
  47. // IotCloudUtil
  48. IotCloudUtil iotCloudUtil = new IotCloudUtil(this);
  49. // 连接云平台
  50. iotCloudUtil.connect();
  51. // 等待几秒钟,连接成功
  52. try {
  53. Thread.sleep(4000);
  54. } catch (InterruptedException e) {
  55. e.printStackTrace();
  56. }
  57. // 调用发送数据的函数需要传入JsonObject类型的数据
  58. JSONObject property = new JSONObject();
  59. try {
  60. property.put("position_x", (float) positionX);
  61. property.put("position_y", (float) positionY);
  62. // 发送数据
  63. Status status = iotCloudUtil.propertyReport(property, null);
  64. if (status == Status.OK){
  65. // 发送成功
  66. }
  67. } catch (JSONException e) {
  68. e.printStackTrace();
  69. }
  70. }

其中GPS工具就不进行介绍了,因为其不是重点,关于具体的代码可以参考GitHub

微信小程序使用

前面我们说了,可以是用微信小程序对开发的物联网设备进行开发调试,然后我们在如下的页面得到设备的二维码。

然后打开”腾讯连连“小程序,对二维码进行扫描,即可将设备加入。

然后我们运行安卓程序,自动向腾讯IOT平台发送经纬度数据,然后在微信小程序上就可以看到最新的数据。

中间存在些许误差,可能是因为double转float的精度原因导致的。

总结

通过上面的操作我们创建了一个安卓程序,然后能够在微信小程序上面看到安卓设备的经纬度。归咎于原理,就是MQTT协议。使用平台提供的SDK,让开发者省下了大量花费在通信协议上面的时间。然而,我们还是应该去关注MQTT协议本身。知其然,更要知其所以然。

参考

  1. Github:android_test_iot_for_tecent

  2. 物联网开发平台使用文档:物联网开发平台 - 文档中心 - 腾讯云 (tencent.com)

  3. Github:iot-device-java

腾讯IOT安卓开发初探的更多相关文章

  1. 腾讯IOT之树莓派物联网设备

    目录 腾讯IOT之树莓派物联网设备 硬件配置 软件配置 Tecent IOT 开发平台的使用 新建项目 新建产品 添加自定义功能 设备开发 微信小程序配置 面板配置 新建设备 使用设备 在线调试 设备 ...

  2. 腾讯优测干货精选| 安卓开发新技能Get -常用必备小工具汇总

    文/腾讯公司 陈江峰 优测小优有话说: 移动研发及测试干货哪里找?腾讯优测-优社区你值得拥有~ 开发同学们都知道,安卓开发路上会碰到很多艰难险阻,一不小心就被KO.这时候,没有新技能傍身怎么行?今天我 ...

  3. C#编写WINNT服务,随便解决安卓开发遇到的5037被众多程序无节操占用的问题

    需求分析: 最近重新开始学习安卓开发,好久不用的ADT集成开发环境频繁遇到不能在仿真机和真机上调试的问题,也就是本人另一篇博文描述的ADB(Android Debug Bridge)监控的5037被金 ...

  4. Unity3D游戏开发初探—2.初步了解3D模型基础

    一.什么是3D模型? 1.1 3D模型概述 简而言之,3D模型就是三维的.立体的模型,D是英文Dimensions的缩写. 3D模型也可以说是用3Ds MAX建造的立体模型,包括各种建筑.人物.植被. ...

  5. Win10 IoT C#开发 4 - UART 串口通信

    Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,既可以开发设备UI与用户交互式操作,又可以控制GPIO等接口,使得原来嵌入式繁琐的开发变得简单.通过Remote Debug ...

  6. 《Windows IoT 应用开发指南》

    物物互联的时代已经到来,智能家居.智慧校园.智慧交通.可穿戴.无人机.全息投影,各种各样的新名词.黑科技层出不穷.当我们为五年前能够通过手机控制家电而欣喜若狂的时候,可曾憧憬过当前使用增强现实设备完成 ...

  7. 基于eclipse-java的平台上搭建安卓开发环境

    首先感谢好人的分享!http://www.mamicode.com/info-detail-516839.html 系统:windows 7 若想直接安装eclipse—android的,请启动如下传 ...

  8. 关于安卓开发当中通过java自带的HttpURLConnection访问XML的java.io.EOFException问题

    刚接触安卓开发,试着写个小程序熟悉下,就写了天气预报的小程序,通过httpUrlConnection读流的方式来获取网络公共接口提供的天气XML信息.但在建立http连接时一直报java.io.EOF ...

  9. Android Studio 1.0.1 + Genymotion安卓模拟器打造高效安卓开发环境

    我们开发安卓大多是使用Eclipse和安卓SDK中自带的安卓模拟器.当然,Google早就推出了自己的安卓开发环境——Android studio,在不久前,Google发布了Android Stud ...

随机推荐

  1. flask中SQLAlchemy学习

    ------------------------------------2019-08-22 17:53:54更新------------------------------ SQLALchemy实在 ...

  2. Geoserver对发布的数据源进行金字塔切片

    一.建立切片数据源 1.1建立工作区 1.2添加数据 我这里是老师给的高清卫星地图数据,格式为tif 工作区选择之前建立的工作区,浏览那里选择对应的文件 1.3建立切片源的图层 这里建立的图层中先不用 ...

  3. 使用T4模板动态生成NPoco实体类

    这是一个妥妥的NPoco类,这是我们在工作开发中,手动去写这个实体类,属实非常心累,字段少无所谓一次两次,数量多了,字段多了,就心态裂开

  4. 从.NET转GO了

    前言 近几个月刚从.NET转到GO,入职了一个使用GO微服务的互联网公司.因为需要熟悉公司的微服务架构和适应新公司的节奏,所以最近没时间写博客,现在简单做个总结. 转GO的经历 自学GO 上一年的八月 ...

  5. 题解 CF1375E Inversion SwapSort

    蒟蒻语 这题是真的奇妙... 想了好久才想明白. 蒟蒻解 考虑冒泡排序是怎样的. 对于相邻的两个数 \(a_i, a_{i+1}\),如果 \(a_i>a_{i+1}\) 那么就交换两个数. 总 ...

  6. stringbuilder和stringbuffer速度比较

    同样的代码,只改了类型,分别为stringbuilder和stringbuffer,只比较一下,执行引擎为hive. 当数据量为100000条,string builder耗时280秒,stringb ...

  7. 谈谈MySQL bin log的写入机制、以及线上的参数是如何配置的

    目录 一.binlog 的高速缓存 二.刷盘机制 三.推荐的策略 推荐阅读 问个问题吧!为什么你需要了解binlog的落盘机制呢? 我来回答一下: ​ 上一篇文章提到了生产环境中你可以使用binlog ...

  8. KafkaMirrorMaker 的不足以及一些改进

    背景 某系统使用 Kafka 存储实时的行情数据,为了保证数据的实时性,需要在多地机房维护多个 Kafka 集群,并将行情数据同步到这些集群上. 一个常用的方案就是官方提供的 KafkaMirrorM ...

  9. JWT 注册登录

    1.JWT安装配置 pip install djangorestframework-jwt==1.11.0 1.2 syl/settings.py 配置jwt载荷中的有效期设置 # jwt载荷中的有效 ...

  10. SpringBoot + SpringSecurity + Quartz + Layui实现系统权限控制和定时任务

    1. 简介   Spring Security是一个功能强大且易于扩展的安全框架,主要用于为Java程序提供用户认证(Authentication)和用户授权(Authorization)功能.    ...