当前位置:   article > 正文

物联网平台搭建的全过程介绍(三)阿里云物联网设备接入订阅发布之Android studio例程

物联网平台搭建的全过程介绍

物联网平台搭建系列内容前两节介绍的都是功能性的描述,今天以一个小例子,介绍具体的设备接入、订阅、发布的操作,例子的名字为:学生成绩录入平台,例子的界面如下图所示。

功能描述:当在阿里云物联网平台内下发学生姓名的时候,“学生姓名”后边会显示这个学生的名字。当在数学、语文后边的输入框内输入分数,并且点“发送”按钮时,会将这两个分数发送到物联网平台。

为了方便更多读者,本例以公共实例为例,通信方式为MQTT,企业实例与此大同小异。阿里云官方网站给的物联网Android sdk示例,其中一整套功能都具备了,程序非常复杂,对于入门级的小白来说,简直就是天书。本例只给出了最基本的设备接入、订阅、发布三个功能的示例。设备接入给出了旧版公共实例(新版的可以在此基础上改动)和企业实例两种方式;订阅功能还给出来数据解析,可以从payload解析出物模型的每一项数据显示在Textview内;发布动能给出了可以从EditText输入数据,并且打包成json格式数据包。

下边对具体操作过程做一介绍:

目录

一、阿里云物联网平台的操作

1、学会参考官网的技术文档

2、创建产品

3、添加物模型

4、添加设备

5、确定host

二、Android studio平台的操作

1、AndroidManifest的设置

(1)开权限

(2)在application内注册service

2、build.gradle(Module:app)

(1)Android下增加

(2)dependencies下的所有依赖

3、layout设计

4、自定义类

5、MainActivity.class

(1)AliyunTopicHostSet(int IotInstanceType)函数

(2)subscribeTopic(String topic)

(3)publishMessage(String payload)

(4)onCreate(Bundle savedInstanceState)

三、源代码


一、阿里云物联网平台的操作

1、学会参考官网的技术文档

(1)进入物联网平台后,选择华东2(上海)服务器

(2)点击公共实例

(3)点“文档与工具”

(4)点“物联网设备接入与管理”

(5)点“设备接入”

 设备接入的文档都在这里,具体链接:设备接入 (aliyun.com)

2、创建产品

具体操作步骤见:创建产品 (aliyun.com)

3、添加物模型

具体操作步骤见:单个添加物模型 (aliyun.com)

本例创建产品和添加物模型的结果如图所示,产品名称为“学生成绩录入平台”。

物模型有三个自定义功能:

序号功能名称标识符数据类型数据定义
1学生姓名student_nametext (字符串)数据长度:32
2语文分数chinese_scorefloat (单精度浮点型)取值范围:0 ~ 100
3数学分数maths_scorefloat (单精度浮点型)取值范围:0 ~ 100

4、添加设备

具体操作步骤见:单个创建设备 (aliyun.com)

也可以批量添加设备,操作步骤见:批量创建设备 (aliyun.com)

在“学生成绩录入平台”内添加一个设备,设备名称为20220001,结果如下图所示:

 点设备页面某个设备所在行最后的“查看”,可进入设备详情页,如下图所示。 

在设备详情页面,点DeviceSecret后边的“查看”,可以查看设备的三要素,如下图所示。

5、确定host

阿里云物联网设备三要素和host是设备接入的必须设置的,host的确定见:查看实例终端节点 (aliyun.com)

本例为旧版公共实例,MQTT的host的格式为:

${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com:1883

${YourProductKey}替换为本产品的ProductKey:a1*****igLp,把${YourRegionId}替换为公共实例的所在区域,本例为华东2(上海),所以为:cn-shanghai。区域代码详见:支持的地域 (aliyun.com)

所以最终的结果:

host="a1*****igLp.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883"

二、Android studio平台的操作

1、AndroidManifest的设置

(1)开权限

  1. <uses-permission android:name="android.permission.WAKE_LOCK" />
  2. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  3. <uses-permission android:name="android.permission.INTERNET" />
  4. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  5. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  6. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  7. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

(2)在application内注册service

  1. <service android:name="org.eclipse.paho.android.service.MqttService">
  2. </service>

2、build.gradle(Module:app)

(1)Android下增加

  1. packagingOptions {
  2. exclude 'META-INF/DEPENDENCIES'
  3. exclude 'META-INF/NOTICE'
  4. exclude 'META-INF/LICENSE'
  5. exclude 'META-INF/LICENSE.txt'
  6. exclude 'META-INF/NOTICE.txt'
  7. }

(2)dependencies下的所有依赖

  1. implementation fileTree(dir: 'libs', include: ['*.jar'])
  2. androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
  3. exclude group: 'com.android.support', module: 'support-annotations'
  4. })
  5. implementation 'androidx.appcompat:appcompat:1.1.0'
  6. implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
  7. testImplementation 'junit:junit:4.12'
  8. androidTestImplementation 'androidx.test.ext:junit:1.1.1'
  9. androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
  10. implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.0'
  11. implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
  12. implementation 'com.android.support:support-v4:28.1.1'

3、layout设计

 一共有7个控件:4个TextView,分别显示学生姓名、数学、语文的标签,以及学生姓名的具体内容。2个EditText,用来输入数学和语文的分数。1个Button,标签为“上传”,点击后进行publish的功能,将语文、数学的两个分数发送到物联网平台。

layout的代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity">
  8. <LinearLayout
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent"
  11. android:layout_marginTop="20dp"
  12. android:layout_marginBottom="0dp"
  13. android:orientation="vertical">
  14. <LinearLayout
  15. android:layout_width="match_parent"
  16. android:layout_height="wrap_content"
  17. android:layout_marginTop="10dp"
  18. android:layout_marginLeft="20dp"
  19. android:layout_marginRight="20dp"
  20. android:gravity="center"
  21. android:orientation="horizontal"
  22. >
  23. <TextView
  24. android:id="@+id/student_name_lable"
  25. android:layout_width="50dp"
  26. android:layout_height="wrap_content"
  27. android:layout_weight="1"
  28. android:layout_marginTop="10dp"
  29. android:gravity="right"
  30. android:textColor="@color/colorPrimary"
  31. android:textSize="30dp"
  32. android:text="学生姓名:"/>
  33. <TextView
  34. android:id="@+id/student_name_content"
  35. android:layout_width="50dp"
  36. android:layout_height="wrap_content"
  37. android:layout_weight="1"
  38. android:gravity="center"
  39. android:layout_marginTop="10dp"
  40. android:textColor="@color/colorPrimary"
  41. android:textSize="30dp"
  42. />
  43. </LinearLayout>
  44. <LinearLayout
  45. android:layout_width="match_parent"
  46. android:layout_height="wrap_content"
  47. android:layout_marginTop="10dp"
  48. android:layout_marginLeft="20dp"
  49. android:layout_marginRight="20dp"
  50. android:gravity="center"
  51. android:orientation="horizontal"
  52. >
  53. <TextView
  54. android:id="@+id/maths_lable"
  55. android:layout_width="50dp"
  56. android:layout_height="wrap_content"
  57. android:layout_weight="1"
  58. android:layout_marginTop="0dp"
  59. android:gravity="right"
  60. android:textColor="@color/colorAccent"
  61. android:textSize="20dp"
  62. android:text="数学:"/>
  63. <EditText
  64. android:id="@+id/maths_score"
  65. android:layout_width="wrap_content"
  66. android:layout_height="wrap_content"
  67. android:layout_weight="1"
  68. android:textSize="20dp"
  69. android:hint="请输入分数"
  70. />
  71. </LinearLayout>
  72. <LinearLayout
  73. android:layout_width="match_parent"
  74. android:layout_height="wrap_content"
  75. android:layout_marginTop="10dp"
  76. android:layout_marginLeft="20dp"
  77. android:layout_marginRight="20dp"
  78. android:gravity="center"
  79. android:orientation="horizontal"
  80. >
  81. <TextView
  82. android:id="@+id/chinese_lable"
  83. android:layout_width="50dp"
  84. android:layout_height="wrap_content"
  85. android:layout_weight="1"
  86. android:layout_marginTop="0dp"
  87. android:gravity="right"
  88. android:textColor="@color/colorAccent"
  89. android:textSize="20dp"
  90. android:text="语文:"/>
  91. <EditText
  92. android:id="@+id/chinese_score"
  93. android:layout_width="wrap_content"
  94. android:layout_height="wrap_content"
  95. android:layout_weight="1"
  96. android:textSize="20dp"
  97. android:hint="请输入分数"
  98. />
  99. </LinearLayout>
  100. <LinearLayout
  101. android:layout_width="match_parent"
  102. android:layout_height="wrap_content"
  103. android:layout_marginTop="10dp"
  104. android:layout_marginLeft="20dp"
  105. android:layout_marginRight="20dp"
  106. android:gravity="center"
  107. android:orientation="horizontal"
  108. >
  109. <Button
  110. android:id="@+id/btn_publish"
  111. android:layout_width="20dp"
  112. android:layout_height="wrap_content"
  113. android:layout_margin="0dp"
  114. android:layout_weight="1"
  115. android:textSize="20dp"
  116. android:text="上传" />
  117. </LinearLayout>
  118. </LinearLayout>
  119. </androidx.constraintlayout.widget.ConstraintLayout>

4、自定义类

本例程定义了一个类AiotMqttOption,作用就是根据物联网平台的设备三元组productKey, deviceName和deviceSecret, 生成Mqtt建连参数clientId,username和password。用到的加密算法是HmacSHA256。

  1. package com.example.mybasicaliyun;
  2. import java.math.BigInteger;
  3. import javax.crypto.Mac;
  4. import javax.crypto.spec.SecretKeySpec;
  5. /**
  6. * MQTT建连选项类,输入设备三元组productKey, deviceName和deviceSecret, 生成Mqtt建连参数clientId,username和password.
  7. */
  8. class AiotMqttOption {
  9. private String username = "";
  10. private String password = "";
  11. private String clientId = "";
  12. String getUsername() { return this.username;}
  13. String getPassword() { return this.password;}
  14. String getClientId() { return this.clientId;}
  15. /**
  16. * 获取Mqtt建连选项对象
  17. * @param productKey 产品秘钥
  18. * @param deviceName 设备名称
  19. * @param deviceSecret 设备机密
  20. * @return AiotMqttOption对象或者NULL
  21. */
  22. public AiotMqttOption getMqttOption(String productKey, String deviceName, String deviceSecret) {
  23. if (productKey == null || deviceName == null || deviceSecret == null) {
  24. return null;
  25. }
  26. try {
  27. String timestamp = Long.toString(System.currentTimeMillis());
  28. // clientId
  29. this.clientId = productKey + "." + deviceName + "|timestamp=" + timestamp +
  30. ",_v=paho-android-1.0.0,securemode=2,signmethod=hmacsha256|";
  31. // userName
  32. this.username = deviceName + "&" + productKey;
  33. // password
  34. String macSrc = "clientId" + productKey + "." + deviceName + "deviceName" +
  35. deviceName + "productKey" + productKey + "timestamp" + timestamp;
  36. String algorithm = "HmacSHA256";
  37. Mac mac = Mac.getInstance(algorithm);
  38. SecretKeySpec secretKeySpec = new SecretKeySpec(deviceSecret.getBytes(), algorithm);
  39. mac.init(secretKeySpec);
  40. byte[] macRes = mac.doFinal(macSrc.getBytes());
  41. password = String.format("%064x", new BigInteger(1, macRes));
  42. } catch (Exception e) {
  43. e.printStackTrace();
  44. return null;
  45. }
  46. return this;
  47. }
  48. }

5、MainActivity.class

MainActivity.class由三个自定义函数和一个方法组成:

三个自定义函数:AliyunTopicHostSet(int IotInstanceType)函数、subscribeTopic(String topic)函数、publishMessage(String payload)函数;

一个方法:onCreate(Bundle savedInstanceState)方法组成。在onCreate方法中会调用三个自定义函数。

(1)AliyunTopicHostSet(int IotInstanceType)函数

此函数的作用是根据阿里云物联网设备三要素生成SUB_TOPICPUB_TOPIChost

此函数有一个参量,为实例的类型,如果为旧版公共实例,参数为0,如果为新版公共实例或者企业版实例,参数为1。

  1. /**
  2. * 根据阿里云物联网设备三要素生成subtopic、pubtopic和host
  3. * @param IotInstanceType 实例类型,0:华东2(上海)服务器公共实例;1:企业实例
  4. */
  5. public void AliyunTopicHostSet(int IotInstanceType) {
  6. SUB_TOPIC ="/sys/" + PRODUCTKEY + "/" + DEVICENAME + "/thing/service/property/set";
  7. PUB_TOPIC = "/sys/"+ PRODUCTKEY + "/" + DEVICENAME + "/user/update";
  8. if(IotInstanceType==0)
  9. {
  10. host="tcp://" + PRODUCTKEY + ".iot-as-mqtt.cn-shanghai.aliyuncs.com:1883";//适用于公共实例华东2(上海)
  11. }
  12. else
  13. {
  14. host="tcp://" + IotInstanceId + ".mqtt.iothub.aliyuncs.com:1883";//试用于企业实例
  15. }
  16. }

(2)subscribeTopic(String topic)

此函数的作用是订阅物联网平台的topic,当物联网平台下发这个topic的数据时,可以接收。

此函数有一个参量,就是SUB_TOPIC

  1. /**
  2. * 订阅特定的主题
  3. * @param topic mqtt主题
  4. */
  5. public void subscribeTopic(String topic) {
  6. try {
  7. mqttAndroidClient.subscribe(topic, 0, null, new IMqttActionListener() {
  8. @Override
  9. public void onSuccess(IMqttToken asyncActionToken) {
  10. Log.i(TAG, "subscribed succeed");
  11. }
  12. @Override
  13. public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
  14. Log.i(TAG, "subscribed failed");
  15. }
  16. });
  17. } catch (MqttException e) {
  18. e.printStackTrace();
  19. }
  20. }

(3)publishMessage(String payload)

此函数的作用是把设备要发送的数据打包成json格式,根据PUB_TOPIC的规则,发送到物联网平台上对应的设备上。此函数有一个参量,为payload,即按照json格式把要发送的数据打成的包

  1. /**
  2. * 向默认的主题/user/update发布消息
  3. * @param payload 消息载荷
  4. */
  5. public void publishMessage(String payload) {
  6. try {
  7. if (!mqttAndroidClient.isConnected()) {
  8. mqttAndroidClient.connect();
  9. }
  10. MqttMessage message = new MqttMessage();
  11. message.setPayload(payload.getBytes());
  12. message.setQos(0);
  13. mqttAndroidClient.publish(PUB_TOPIC, message,null, new IMqttActionListener() {
  14. @Override
  15. public void onSuccess(IMqttToken asyncActionToken) {
  16. Log.i(TAG, "publish succeed!");
  17. }
  18. @Override
  19. public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
  20. Log.i(TAG, "publish failed!");
  21. }
  22. });
  23. } catch (MqttException e) {
  24. Log.e(TAG, e.toString());
  25. e.printStackTrace();
  26. }
  27. }

(4)onCreate(Bundle savedInstanceState)

此方法完整代码如下所示:

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. setContentView(R.layout.activity_main);
  5. tv_student_name=this.findViewById(R.id.student_name_content);
  6. et_maths_score=this.findViewById(R.id.maths_score);
  7. et_chinese_score=this.findViewById(R.id.chinese_score);
  8. btn_publish= findViewById(R.id.btn_publish);
  9. //根据阿里云三要素构建subtopic、pubtopic、host
  10. AliyunTopicHostSet(0);
  11. //MQTT建连选项类,输入设备三元组productKey, deviceName和deviceSecret, 生成Mqtt建连参数clientId,username和password
  12. AiotMqttOption aiotMqttOption = new AiotMqttOption().getMqttOption(PRODUCTKEY, DEVICENAME, DEVICESECRET);
  13. if (aiotMqttOption == null) {
  14. Log.e(TAG, "device info error");
  15. } else {
  16. clientId = aiotMqttOption.getClientId();
  17. userName = aiotMqttOption.getUsername();
  18. passWord = aiotMqttOption.getPassword();
  19. }
  20. /* Mqtt建连 */
  21. try {
  22. /* 创建MqttConnectOptions对象并配置username和password */
  23. final MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
  24. mqttConnectOptions.setUserName(userName);
  25. mqttConnectOptions.setPassword(passWord.toCharArray());
  26. /* 创建MqttAndroidClient对象, 并设置回调接口 */
  27. //String plstring;
  28. mqttAndroidClient = new MqttAndroidClient(getApplicationContext(), host, clientId);
  29. mqttAndroidClient.connect(mqttConnectOptions,null, new IMqttActionListener() {
  30. //连接成功方法
  31. @Override
  32. public void onSuccess(IMqttToken asyncActionToken) {
  33. Log.i(TAG, "connect succeed");
  34. subscribeTopic(SUB_TOPIC);
  35. }
  36. //连接失败方法
  37. @Override
  38. public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
  39. Log.i(TAG, "connect failed");
  40. }
  41. });
  42. } catch (MqttException e) {
  43. e.printStackTrace();
  44. }
  45. /**
  46. * mqtt回调类,此类内包含三个方法:connectionLost(掉线),messageArrived(订阅消息到达),deliveryComplete(发布消息送达)
  47. */
  48. mqttAndroidClient.setCallback(new MqttCallback() {
  49. //连接中断方法
  50. @Override
  51. public void connectionLost(Throwable cause) {
  52. Log.i(TAG, "connection lost");
  53. }
  54. @SuppressLint("SetTextI18n")
  55. @Override
  56. //订阅消息后,消息到达时方法
  57. public void messageArrived(String topic, MqttMessage message) throws Exception {
  58. Log.i(TAG, "topic: " + topic + ", msg: " + new String(message.getPayload()));
  59. String payload = new String(message.getPayload());
  60. JSONObject Jobj_payload = new JSONObject(payload);
  61. JSONObject Jobj_params=new JSONObject(Jobj_payload.getString("params"));
  62. String student_name=Jobj_params.getString("student_name");
  63. if( (Jobj_params.has("student_name")))
  64. {
  65. System.out.println(student_name);
  66. tv_student_name.setText(student_name);
  67. }
  68. }// messageArrived类结束标志
  69. //发布消息后,消息投递成功后返回方法
  70. @Override
  71. public void deliveryComplete(IMqttDeliveryToken token) {
  72. Log.i(TAG, "msg delivered");
  73. }
  74. });//mqttAndroidClient.setCallback类结束标志
  75. /**
  76. * 点"上传"按钮后,将数学、语文分数发送到阿里云物联网平台
  77. */
  78. btn_publish.setOnClickListener((view)-> {
  79. int maths_score=Integer.parseInt(et_maths_score.getText().toString());
  80. int chinese_score=Integer.parseInt(et_chinese_score.getText().toString());
  81. //发布消息的payload数据包生成方法一:利用JSONObject,分两层将params内的数学、语文分数,和params外的id,version打成一个json数据包
  82. JSONObject Jobj_payload = new JSONObject();
  83. JSONObject Jobj_params = new JSONObject();
  84. try {
  85. Jobj_params.put("maths_score",maths_score);
  86. Jobj_params.put("chinese_score",chinese_score);
  87. Jobj_payload.put("id", DEVICENAME);
  88. Jobj_payload.put("version", "1.0");
  89. Jobj_payload.put("params", Jobj_params);
  90. } catch (JSONException e) {
  91. e.printStackTrace();
  92. }
  93. publishMessage(Jobj_payload.toString());
  94. 发布消息的payload数据包生成方法二:利用构建字符串的方法,按照json格式把字符和变量连接起来,形成一个json数据字符串。
  95. // String Jobj_payload_string="{\"id\":\"" +DEVICENAME+ "\", \"version\":\"1.0\"" + ",\"params\":{\"maths_score\":"+ et_maths_score.getText().toString() +",\"chinese_score\":"+chinese_score+"}}";
  96. // publishMessage(Jobj_payload_string);
  97. });
  98. }//oncreat结束标志

此方法包含七部分:

第一部分:关联layout、TextView、EditText和Button。

  1. setContentView(R.layout.activity_main);
  2. tv_student_name=this.findViewById(R.id.student_name_content);
  3. et_maths_score=this.findViewById(R.id.maths_score);
  4. et_chinese_score=this.findViewById(R.id.chinese_score);
  5. btn_publish= findViewById(R.id.btn_publish);

第二部分:AliyunTopicHostSet(int IotInstanceType)函数,旧版公共实例,IotInstanceType为0;

  1. //根据阿里云三要素构建subtopic、pubtopic、host
  2. AliyunTopicHostSet(0);

第三部分:新建AiotMqttOption对象,为mqtt的联网做准备。

  1. //MQTT建连选项类,输入设备三元组productKey, deviceName和deviceSecret, 生成Mqtt建连参数clientId,username和password
  2. AiotMqttOption aiotMqttOption = new AiotMqttOption().getMqttOption(PRODUCTKEY, DEVICENAME, DEVICESECRET);
  3. if (aiotMqttOption == null) {
  4. Log.e(TAG, "device info error");
  5. } else {
  6. clientId = aiotMqttOption.getClientId();
  7. userName = aiotMqttOption.getUsername();
  8. passWord = aiotMqttOption.getPassword();
  9. }

第四部分:创建MqttConnectOptions对象和mqttAndroidClient对象,利用mqttAndroidClient.connect的方法进行mqtt连网操作。mqttAndroidClient.connect方法中还包含mqtt连网成功onSuccess方法和mqtt连网失败onFailure方法。本例的订阅函数就是在onSuccess方法中调用的。

  1. /* Mqtt建连 */
  2. try {
  3. /* 创建MqttConnectOptions对象并配置username和password */
  4. final MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
  5. mqttConnectOptions.setUserName(userName);
  6. mqttConnectOptions.setPassword(passWord.toCharArray());
  7. /* 创建MqttAndroidClient对象, 并设置回调接口 */
  8. //String plstring;
  9. mqttAndroidClient = new MqttAndroidClient(getApplicationContext(), host, clientId);
  10. mqttAndroidClient.connect(mqttConnectOptions,null, new IMqttActionListener() {
  11. //连接成功方法
  12. @Override
  13. public void onSuccess(IMqttToken asyncActionToken) {
  14. Log.i(TAG, "connect succeed");
  15. subscribeTopic(SUB_TOPIC);
  16. }
  17. //连接失败方法
  18. @Override
  19. public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
  20. Log.i(TAG, "connect failed");
  21. }
  22. });
  23. } catch (MqttException e) {
  24. e.printStackTrace();
  25. }

第五部分:mqttAndroidClient的回调方法setCallback,此方法又包含两个方法。其中messageArrived方法为订阅的消息到达时触发,deliveryComplete方法为发布消息送达时触发。本例在messageArrived方法里对接收到的下发消息进行joson解析并提取。

  1. /**
  2. * mqtt回调类,此类内包含三个方法:connectionLost(掉线),messageArrived(订阅消息到达),deliveryComplete(发布消息送达)
  3. */
  4. mqttAndroidClient.setCallback(new MqttCallback() {
  5. //连接中断方法
  6. @Override
  7. public void connectionLost(Throwable cause) {
  8. Log.i(TAG, "connection lost");
  9. }
  10. @SuppressLint("SetTextI18n")
  11. @Override
  12. //订阅消息后,消息到达时方法
  13. public void messageArrived(String topic, MqttMessage message) throws Exception {
  14. Log.i(TAG, "topic: " + topic + ", msg: " + new String(message.getPayload()));
  15. String payload = new String(message.getPayload());
  16. JSONObject Jobj_payload = new JSONObject(payload);
  17. JSONObject Jobj_params=new JSONObject(Jobj_payload.getString("params"));
  18. String student_name=Jobj_params.getString("student_name");
  19. if( (Jobj_params.has("student_name")))
  20. {
  21. System.out.println(student_name);
  22. tv_student_name.setText(student_name);
  23. }
  24. }// messageArrived类结束标志
  25. //发布消息后,消息投递成功后返回方法
  26. @Override
  27. public void deliveryComplete(IMqttDeliveryToken token) {
  28. Log.i(TAG, "msg delivered");
  29. }
  30. });//mqttAndroidClient.setCallback类结束标志

第六部分:btn_publish.setOnClickListener方法,“发送”按钮被按下后触发,此方法内将数学、语文分数按照物模型的规则打包成json数据包,并且调用publishMessage方法把数据发送到物联网平台。阿里云物联网要求的发送到物联网平台的数据json格式的物模型如下所示:

  1. {
  2. "id":"20210001",
  3. "version":"1.0",
  4. "params":
  5. {
  6. "maths_score":maths_score,
  7. "chinese_score":chinese_score
  8. }
  9. }

所以按照上述格式,程序中首先把maths_score、chinese_score以键值对的形式放进里层的parms数据包里,然后再把id、version、params放进外层的数据包里,程序如下图所示:

  1. /**
  2. * 点"上传"按钮后,将数学、语文分数发送到阿里云物联网平台
  3. */
  4. btn_publish.setOnClickListener((view)-> {
  5. int maths_score=Integer.parseInt(et_maths_score.getText().toString());
  6. int chinese_score=Integer.parseInt(et_chinese_score.getText().toString());
  7. //发布消息的payload数据包生成方法一:利用JSONObject,分两层将params内的数学、语文分数,和params外的id,version打成一个json数据包
  8. JSONObject Jobj_payload = new JSONObject();
  9. JSONObject Jobj_params = new JSONObject();
  10. try {
  11. Jobj_params.put("maths_score",maths_score);
  12. Jobj_params.put("chinese_score",chinese_score);
  13. Jobj_payload.put("id", DEVICENAME);
  14. Jobj_payload.put("version", "1.0");
  15. Jobj_payload.put("params", Jobj_params);
  16. } catch (JSONException e) {
  17. e.printStackTrace();
  18. }
  19. publishMessage(Jobj_payload.toString());
  20. 发布消息的payload数据包生成方法二:利用构建字符串的方法,按照json格式把字符和变量连接起来,形成一个json数据字符串。
  21. // String Jobj_payload_string="{\"id\":\"" +DEVICENAME+ "\", \"version\":\"1.0\"" + ",\"params\":{\"maths_score\":"+ et_maths_score.getText().toString() +",\"chinese_score\":"+chinese_score+"}}";
  22. // publishMessage(Jobj_payload_string);
  23. });

第七部分:声明变量部分,这部分比较简单,不再介绍,程序如下所示。

  1. /* 设备三元组信息 */
  2. private String IotInstanceId="";
  3. private String PRODUCTKEY="a1********p";
  4. private String DEVICENAME="20220001";
  5. private String DEVICESECRET="a3**************************7277";
  6. /* 自动Topic, 用于上报消息 */
  7. private String PUB_TOPIC;
  8. /* 自动Topic, 用于接受消息 */
  9. private String SUB_TOPIC;
  10. /* 阿里云Mqtt服务器域名 */
  11. String host;
  12. /*Mqtt建连参数*/
  13. private String clientId;
  14. private String userName;
  15. private String passWord;
  16. //设置log.e的TAG
  17. private final String TAG = "AiotMqtt";
  18. MqttAndroidClient mqttAndroidClient;
  19. //ui相关变量
  20. TextView tv_student_name;
  21. EditText et_maths_score,et_chinese_score;
  22. Button btn_publish;

三、源代码

本例完整源代码请点击下载

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/535872
推荐阅读
相关标签
  

闽ICP备14008679号