本例源代码请点:下载
在上一节物联网平台搭建的全过程介绍(三)阿里云物联网设备接入订阅发布之Android studio例程
介绍了一台设备与阿里云物联网平台之间的接入、订阅和发布的功能。但做到这一步还远远不够,对于远程控制来说,需要一台设备能与另外一台设备进行通信。
如下图所示,两台设备之间进行通信的步骤:第一,实际设备一、二按照虚拟设备一、二的阿里云三要素接入物联网平台;第二,两台设备按着实际的需求设计好订阅和发布的功能;第三,通过云数据流转建立起两台设备通信的通道。
下边就对以上三步进行详细介绍。
目录
一、两台设备接入物联网平台
此部分操作,与第三节完全一样,第三节中在阿里云平台“学生成绩录入平台”产品下建立了20220001设备,今天再新建一个20220002,并将三要素和host记录下来。
二、两台设备设计订阅和发布的功能
功能设计为:一台设备连接20220001,一台设备连接20220002。当一台设备发送学生姓名、数学成绩、语文成绩后,另一台设备可以接收到,并且在屏幕上显示出来。如下图所示,界面上半部分用于显示接收到的信息,下半部分用于输入信息,当点击“上传”按钮后将输入信息发送到另外一台设备。
界面与第三节相比:显示部分增加了数学分数、语文分数;信息输入部分增加了学生姓名。
1、订阅代码
(1)第三节解析代码
第三节中订阅功能的测试是用物联网平台设备模拟器下发属性值来实现的,具体操作见下图:
设备模拟器下发的数据包payload的格式
{
"method":"thing.service.property.set",
"id":"1473562965",
"params":
{
"student_name":"张三"
},
"version":"1.0.0"
}
所以在程序中需要先从payload中把“params”内容提取出来,然后再从“params”中把"student_name"内容提取出来。
String payload = new String(message.getPayload());
//把payload转成json格式
JSONObject Jobj_payload = new JSONObject(payload);
//把params内容从payload中解析出来
JSONObject Jobj_params=new JSONObject(Jobj_payload.getString("params"));
//把student_name内容从params中解析出来
String student_name=Jobj_params.getString("student_name");//
(2)本节解析代码
本节订阅功能的测试是用一台发送信息,另一台接收信息。是通过数据流转功能实现的,那么payload内容与解析器脚本有关。数据流转的操作可见:https://blog.csdn.net/m0_72963799/article/details/126555344?spm=1001.2014.3001.5502阿里云物联网Iot设备上下线状态数据流转的设置
数据源:
数据目的:
解析器脚本:
var data = payload("json"); var select = {}; select.put("student_name", getOrNull(data,"items","student_name","value")); select.put("maths_score", getOrNull(data,"items","maths_score","value")); select.put("chinese_score", getOrNull(data,"items","chinese_score","value")); //如果是设备20220001发来的消息,就流转到20220002 if(deviceName()=="20220001") { writeIotTopic(1002, "/sys/a1UYYHkigLp/20220002/thing/service/property/set", select); } //如果是设备20220002发来的消息,就流转到20220001 if(deviceName()=="20220002") { writeIotTopic(1002, "/sys/a1UYYHkigLp/20220001/thing/service/property/set", select); }
注意此脚本,只将student_name、maths_score、chinese_score打包进行了流转,所以接收设备接收到的payload格式为:
{
"student_name":"张三",
"maths_score":80,
"chinese_score":90
}
所以,可以直接从payload中解析student_name、maths_score、chinese_score的内容。代码如下:
//订阅消息后,消息到达时方法
public void messageArrived(String topic, MqttMessage message) throws Exception {
Log.i(TAG, "topic: " + topic + ", msg: " + new String(message.getPayload()));
String payload = new String(message.getPayload());
//以下两句代码注释
//JSONObject Jobj_payload = new JSONObject(payload);
//JSONObject Jobj_params=new JSONObject(Jobj_payload.getString("params"));
JSONObject Jobj_params = new JSONObject(payload);//新增代码
String student_name=Jobj_params.getString("student_name");//新增代码
double maths_score=Jobj_params.getDouble("maths_score");
double chinese_score=Jobj_params.getDouble("chinese_score");
System.out.println(student_name);
System.out.println(maths_score);
if( (Jobj_params.has("student_name")))
{
System.out.println(student_name);
tv_student_name.setText(student_name);
tv_maths_score.setText(Double.toString(maths_score));
tv_chinese_score.setText(Double.toString(chinese_score));
}
}// messageArrived类结束标志
2、发送代码
此部分代码与第三节的区别在于:发送的数据增加了student_name。
/**
* 点"上传"按钮后,将数学、语文分数发送到阿里云物联网平台
*/
btn_publish.setOnClickListener((view)-> {
double maths_score=Double.parseDouble(et_maths_score.getText().toString());
double chinese_score=Double.parseDouble(et_chinese_score.getText().toString());
String student_name=et_student_name.getText().toString();
//发布消息的payload数据包生成方法一:利用JSONObject,分两层将params内的数学、语文分数,和params外的id,version打成一个json数据包
JSONObject Jobj_payload = new JSONObject();
JSONObject Jobj_params = new JSONObject();
try {
Jobj_params.put("student_name",student_name);
Jobj_params.put("maths_score",maths_score);
Jobj_params.put("chinese_score",chinese_score);
Jobj_payload.put("id", DEVICENAME);
Jobj_payload.put("version", "1.0");
Jobj_payload.put("params", Jobj_params);
} catch (JSONException e) {
e.printStackTrace();
}
publishMessage(Jobj_payload.toString());
});
三、测试
四、源代码
本例源代码请点:下载