Agent Lite SDK使用指南(Android)(联通用户专用)
非联通用户请查看设备接入服务。
按照本文档的指导,开发者可以体验直连设备通过集成Agent Lite快速接入平台,体验“数据上报”、“命令接收”、“添加非直连设备”等功能。
Agent Lite以SDK的形式嵌入第三方软件中。本文档以Agent Lite Android Demo为例,指导开发者使用Agent Lite SDK中的接口,实现“直连设备登录”、“数据上报”和“命令下发”等功能。
- 开发者可以基于Agent Lite Android Demo开发,也可参考Agent Lite Android Demo,自行集成Agent Lite SDK(Android)。
- Agent Lite Android Demo使用的IDE工具为Android Studio。
使用必读
开发环境要求:
Android系统:API_LEVEL21及以上。
工程目录结构及文件说明:
目录结构 |
目录 |
说明 |
---|---|---|
Agent LiteDemo │ ├─src │ └─com │ └─huawei │ └─agentlitedemo ├─gen ├─assets │ └─conf ├─bin ├─libs │ └─armeabi └─res |
src |
存放Agent Lite Demo代码 |
libs |
存放Agent Lite提供的jar包和第三方jar包 |
|
armeabi |
存放Agent Lite编译后的库文件和第三方库文件 |
|
conf |
存放TLS证书文件、配置文件 |
如果开发者没有设备,可以直接在X86 Linux系统进行开发。
导入样例代码及配置AndroidStudio
导入样例代码:
- 将Agent Lite Demo(Android)解压到本地。
SDK在Demo中libs文件中。
- 导入android工程。
注:请确保本地计算机网络正常,才能下载需要的SDK和gradle包等资源。
- 打开Android Studio,在“file”菜单中选择“open”。
- 在打开的界面中输入AgentLiteDemo所在的路径,选择“AgentLiteDemo”,点击“OK”。
- 打开菜单“Android 7.1.1(Nougat)”。
- 等待SDK下载安装完毕,重新编译工程,选择菜单
即可。如果编译过程出现问题,需要修改AndroidStudio配置,请参考下一章节的内容。
配置AndroidStudio:
推荐使用AndroidStudio 2.X.X版本,如2.3.1。推荐理由:版本相对稳定,下载插件时不会出现后续版本的各种问题,各版本在功能方面实际上差不多。
- 设置Gradle和Plugin版本。
Gradle和Plugin的版本之间有配套关系,请参考:https://developer.android.com/studio/releases/gradle-plugin。
设置Gradle和Plugin版本时,需要注意在https://services.gradle.org/distributions/和http://jcenter.bintray.com/com/android/tools/build/gradle/目录下是否有所设置的版本(可在浏览器中打开两个网址查看)。
- 设置Android SDK版本。
- 代理配置。
初始化
在发起业务前,需要先初始化Agent Lite相关资源,调用API接口BaseService.init(),初始化Agent Lite资源,具体API的参数使用参考Agent Lite API接口文档。可参考“AgentLiteMain.java”中onCreate()方法对BaseService.init()的调用。
1
|
BaseService.init(WORK_PATH, LOG_PATH, context); |
- “WORK_PATH”为工作路径,不能为空。
- “LOG_PATH”为打印日志路径,当“LOG_PATH”为空时,打印路径默认为工作路径,开发者也可以自己定义打印日志路径。
绑定和登录
设备或网关第一次接入IoT联接管理平台时需要进行绑定操作,从而将设备或网关与平台进行关联。开发者通过传入设备序列号以及设备信息,将设备或网关绑定到物联网平台。
设备或网关绑定成功后或重启后,需要进行登录的流程,在设备或网关成功登录物联网平台后,才可以进行其它服务操作,比如接入其他传感器,数据上报等等。如果设备或网关登录成功,那么设备或网关在平台的状态显示为已在线。
- 修改绑定参数。
绑定时使用的设备固有信息(如设备型号等)是从“config.properties”文件中读取的,所以需要修改./app/src/main/assets/conf目录下config.properties文件中的如下信息:
- “platformIP”:物联网平台的设备对接地址(MQTTS),可参考平台对接信息获取。
- “verifyCode”(设备的标识)和必要的设备信息,包括“Manufacture”(厂商Id)、“deviceType”(设备类型)、“HardwareModel”(设备模型)和“protocolType”(协议类型),其中“manufacturerId”(厂商Id)、“deviceType”(设备类型)、“HardwareModel”(设备模型)和“protocolType”(协议类型)与Profile文件中的定义保持一致。
- 如果通过“设备管理服务控制台”注册设备,则“verifyCode”填写为设备注册时的“preSecret”(预置密钥)。
- 如果通过开发中心注册设备,则“verifyCode”填写为设备注册后返回的“nodeId”(设备标识)。
“config.properties”文件中设备固有示例:
platformIP=100.100.100.100 mqttPort=8883 httpPort=8943 verifyCode=0123456789 Manufacturer=Huawei HardwareModel=AgentLite01 deviceType=Gateway protocolType=HuaweiM2M
- 绑定设备。
调用API接口BindConfig.setConfig()设置绑定配置。
1 2 3 4 5 6
private void startBind() { .... configBindPara(); registerBindReceiver(); ... }
1 2 3 4
private void configBindPara() { BindConfig.setConfig(BindConfig.BIND_CONFIG_ADDR, AgentLiteUtil.get(ConfigName.platformIP)); BindConfig.setConfig(BindConfig.BIND_CONFIG_PORT, AgentLiteUtil.get(ConfigName.httpPort)); }
注册广播接收器对设备绑定结果进行相应处理。
1
LocalBroadcastManager.getInstance(this).registerReceiver(mBindStatusReceiver, new IntentFilter(BindService.TOPIC_BINDDEVICE_RSP));
调用API接口BindService .bind(String verifyCode, IotaDeviceInfo deviceInfo)绑定设备,主要入参为“verifyCode”(设备验证码)和必要的设备信息,包括“nodeId”(设备标识码)、“Manufacture”(厂商Id)、“deviceType”(设备类型)、“HardwareModel”(设备模型)和“protocolType”(协议类型),其中“verifyCode”的值与“nodeId”保持一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
private void startBind() { LogUtil.i(this, TAG, "startBind"); String nodeId = AgentLiteUtil.get(ConfigName.verifyCode); String verifyCode = AgentLiteUtil.get(ConfigName.verifyCode); String manufacturerId = AgentLiteUtil.get(ConfigName.Manufacturer); String deviceType = AgentLiteUtil.get(ConfigName.deviceType); String model = AgentLiteUtil.get(ConfigName.HardwareModel); String protocolType = AgentLiteUtil.get(ConfigName.protocolType); IotaDeviceInfo deviceInfo = new IotaDeviceInfo(nodeId, manufacturerId, deviceType, model, protocolType); ... BindService.bind(verifyCode, deviceInfo); }
设备或网关绑定成功,后续就不需要再绑定了,除非设备或网关被删除,才需要重新绑定。
设备绑定成功会收到广播,广播内容请参考Agent Lite API接口文档中设备绑定接口的返回结果说明和demo中mBindStatusReceiver函数的处理。
- 配置登录参数。
登录前需要通过参数配置接口LoginConfig.setConfig()传入所需的登录信息。
- “设备Id”(即网关Id, “LOGIN_CONFIG_DEVICEID”),“appId”(“LOGIN_CONFIG_APPID”)和“密码”(“LOGIN_CONFIG_SECRET”),这些信息是都是从网关绑定成功的广播中得到的。
- “平台HTTP地址”(“LOGIN_CONFIG_IOCM_ADDR”)和“MQTT地址”(“LOGIN_CONFIG_MQTT_ADDR”)一般是同一个地址,可以从绑定成功的广播中得到。一般情况下,这个地址和Agent Lite设备或网关对接的平台地址一致。
- 绑定成功的广播参数获取可以参考mBindStatusReceiver函数的处理。
1 2 3 4 5 6 7 8 9
private void configLoginPara() { LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_DEVICEID, GatewayInfo.getDeviceID()); LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_APPID, GatewayInfo.getAppID()); LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_SECRET, GatewayInfo.getSecret()); LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_IOCM_ADDR, GatewayInfo.getHaAddress()); LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_IOCM_PORT, "8943"); LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_MQTT_ADDR, GatewayInfo.getHaAddress()); LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_MQTT_PORT, "8883"); }
- 设备登录。
注册广播接收器对设备登录结果进行相应处理。
1
LocalBroadcastManager.getInstance(this).registerReceiver(LoginConnectReceiver, new IntentFilter(LoginService.TOPIC_LOGIN_CONNECTED));
调用LoginService.login()进行直连设备登录,具体API的参数使用参考Agent Lite接口文档中设备登录接口的说明。
1 2 3 4 5
private void startLogin() { LogUtil.i(this, TAG, "startLogin"); configLoginPara(); LoginService.login(); }
编译安装程序
绑定和登录功能完成后,可以先测试一下网关是否能正常与平台对接,再进行后续功能开发。
- 将Android设备连到计算机上,点击“”按钮编译安装工程到Android设备上。
- 在Android设备上运行AgentLiteDemo,修改“平台IP”、“MQTT端口”、“HTTP端口”和“verifyCode”等值。
- “平台IP”、“MQTT端口”和“HTTP端口”可以从物联网平台环境开发中心的“对接信息”界面获取。
- “verifyCode”则是设备的标识,每个设备对应一个verifyCode,不可重复,所以建议使用IMEI或者MAC地址等天然的设备标识。AgentLiteDemo可以在界面上人工输入设备的verifyCode,测试时只要输入一个没有使用过的verifyCode即可。
上传Profile并注册设备
下载Profile开发示例,并上传模板中的profile文件:“Gateway_Huawei_AgentLite01.zip”和“Motion_Huawei_test01.zip”。
设备上线
- 点击AgentLiteDemo上的“BIND”按钮,查看界面上打印出的“设备日志”。
- 当出现“AgentLiteLogin Login Success”,表示AgentLite登录平台成功。
数据上报和数据发布
设备或网关向物联网平台上报数据可以通过调用SDK的“设备服务数据上报”接口或“数据发布”接口:
- “设备服务数据上报”接口:deviceId,requstId和serviceId由SDK组装为消息的header;serviceProperties由SDK组装为消息的body。消息组装格式为JSON。
设备或网关登录成功后可以调用DataTransService.dataReport(int cookie, String requstId, String deviceId, String serviceId, String serviceProperties)接口上报数据。
- 当设备主动上报数据时,“requstId”可以为空。
- 当上报的数据为某个命令的响应时,“requstId”必须与下发命令中的“requstId”保持一致。requestId可以从广播中获取,请参考API文档中“设备命令接收”接口的广播参数“DATATRANS_IE_REQUESTID”的说明。
- “serviceId”要与profile中定义的某个serviceId保持一致,否则无法上报数据。
- “serviceProperties”实际上是一个json字符串,内容是健值对(可以有多组健值对)。每个健是profile中定义的属性名(propertyName),值就是具体要上报的内容了。
1 2 3 4 5 6 7 8 9 10
private void gatewayDataReport() { LogUtil.i(this, TAG, "gatewayDataReport!"); int cookie; String deviceId = GatewayInfo.getDeviceID(); Random random = new Random(); cookie = random.nextInt(65535); LogUtil.i(this, TAG, "cookie = " + cookie); DataTransService.dataReport(cookie, null, deviceId, "Storage", "{\"storage\":10240,\"usedPercent\":20}"); }
注册广播接收器对网关数据上报结果进行相应处理。
1
LocalBroadcastManager.getInstance(this).registerReceiver(dataReportRsp, new IntentFilter(DataTransService.TOPIC_DATA_REPORT_RSP));
- “数据发布”接口:topic固定为“/cloud/signaltrans/v2/categories/data”;“serviceData”参数作为消息体(包括header和body),SDK只进行透传,不进行格式调整和组装。
设备或网关登录成功后可以调用DataTransService. mqttDataPub(int cookie, String topic, int qos, byte[] serviceData)接口发布数据。
- “Topic”是要发布数据的topic。
- “Qos”是mqtt协议的一个参数。
- “serviceData”实际上是一个json字符串,内容是健值对(可以有多组健值对)。每个健是profile中定义的属性名(propertyName),值就是具体要上报的内容了。
1 2 3
private void gatewayDataPub(int cookie, String topic, int qos, byte[] serviceData) { DataTransService. mqttDataPub(cookie, topic, qos, serviceData); }
注册广播接收器对网关数据上报结果进行相应处理。
1
LocalBroadcastManager.getInstance(this).registerReceiver(mqttDataPubRsp, new IntentFilter(DataTransService.TOPIC_MQTT_PUB_RSP));
命令接收
当开发者希望设备或网关只接收topic为“/gws/deviceid/signaltrans/v2/categories/”的消息,且对消息中的header进行解析时,可以调用“设备命令接收”接口。
应用服务器可以调用物联网平台的应用侧API接口给设备或网关下发命令,所以设备或网关需要随时检测命令下发的广播,以便在接收到命令时进行相应业务处理。
注册DataTransService.TOPIC_COMMAND_RECEIVE广播接收器对命令下发进行相应处理。
1
|
LocalBroadcastManager.getInstance(this).registerReceiver(commandReceiver, new IntentFilter(DataTransService.TOPIC_COMMAND_RECEIVE)); |
具体的处理函数commandReceiver:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
private BroadcastReceiver commandReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { IotaMessage iotaMsg = (IotaMessage) intent.getSerializableExtra(DataTransService.DATATRANS_BROADCAST_IE_IOTAMSG); String deviceId = iotaMsg.getString(DataTransService.DATATRANS_IE_DEVICEID); String requestId = iotaMsg.getString(DataTransService.DATATRANS_IE_REQUSTID); String serviceId = iotaMsg.getString(DataTransService.DATATRANS_IE_SERVICEID); String method = iotaMsg.getString(DataTransService.DATATRANS_IE_METHOD); String cmd = iotaMsg.getString(DataTransService.DATATRANS_IE_CMDCONTENT); if (method.equals("REMOVE") && deviceId.equals(sensorId)) { //do something, e.g. show a dialog //rmvSensor(); } LogUtil.i(AgentLiteLogin.this, TAG, "Receive cmd :" + "\ndeviceId = " + deviceId + "\nrequestId = " + requestId + "\nserviceId = " + serviceId + "\nmethod = " + method + "\ncmd = " + cmd); } }; |
在开发中心的“删除”按钮,这样就能在demo界面上看到广播接收时的日志打印命令下发。
界面中,单击非直连设备列后的非直连设备的删除需要网关的确认,正常业务情况下,网关又需要跟具体的设备确认,所以收到删除非直连设备的命令也不会将设备删除。
添加非直连设备
在添加非直连设备前,确认非直连设备的profile已经上传了,详见上传Profile并注册设备步骤。
在设备或网关登录成功后就可以调用HubService.addDevice(int cookie, IotaDeviceInfo deviceInfo)接口添加非直连设备。
这里非直连设备的设备固有信息是测试数据。真实情况下,网关往往需要跟具体的非直连设备交互,才能得到具体的设备固有信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
private void addSensor() { SharedPreferences preferences = getSharedPreferences("AgentLiteDemo", MODE_PRIVATE); if (preferences.getString("SENSORID", null) != null) { Toast.makeText(this, "The sensor is already added.", Toast.LENGTH_SHORT).show(); return; } LogUtil.i(this, TAG, "addSensor!"); int cookie; Random random = new Random(); cookie = random.nextInt(65535); IotaDeviceInfo deviceInfo = new IotaDeviceInfo("0123456test", "Huawei", "Motion", "test01", "MQTT"); HubService.addDevice(cookie, deviceInfo); } |
注册广播接收器对添加设备结果进行相应处理。添加非直连设备成功后就能从广播中得到非直连设备的“deviceId”。
1
|
LocalBroadcastManager.getInstance(this).registerReceiver(addDeviceReceiver, new IntentFilter(HubService.TOPIC_ADDDEV_RSP)); |
非直连设备添加成功后可以在“设备列表”中看到新增一条记录。
非直连设备状态更新
非直连设备添加上时,一般情况下是“离线”状态。所以在非直连设备添加成功后,或者在非直连设备上报数据前,要调用HubService.updateDeviceStatus(int cookie, String deviceId, String status, String statusDetail)进行设备状态更新。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
private void updateDeviceStatus(String status, String statusDetail) { LogUtil.i(this, TAG, "updateDeviceStatus!"); int cookie; Random random = new Random(); cookie = random.nextInt(65535); SharedPreferences preferences = getSharedPreferences("AgentLiteDemo", MODE_PRIVATE); String deviceId = preferences.getString("SENSORID", null); if (deviceId != null) { HubService.updateDeviceStatus(cookie, deviceId, status, statusDetail); } } |
AgentLiteDemo中只添加了一个非直连设备,所以updateDeviceStatus()方法中使用的“deviceId”是直接从SharedPreferences中读取的。
注册广播接收器对非直连设备状态更新结果进行相应处理。
1
|
LocalBroadcastManager.getInstance(this).registerReceiver(devStatusUpdateReceiver, new IntentFilter(HubService.TOPIC_DEVSTATUS_RSP)); |
非直连设备数据上报
请参考数据上报和数据发布章节,调用DataTransService.dataReport或DataTransService. mqttDataPub接口进行数据上报,各个参数使用非直连设备的相关数据即可,此处不再复述。
设备数据上报成功后,可以在非直连设备的“历史数据”中查看上报的数据。