更新时间:2023-04-07 GMT+08:00
分享

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

导入样例代码:

  1. Agent Lite Demo(Android)解压到本地。

    SDK在Demo中libs文件中。

  2. 导入android工程。

    注:请确保本地计算机网络正常,才能下载需要的SDK和gradle包等资源。

    • 打开Android Studio,在“file”菜单中选择“open”
    • 在打开的界面中输入AgentLiteDemo所在的路径,选择“AgentLiteDemo”,点击“OK”

    • 打开菜单Tools > Android > SDK Manager ,在弹出的对话框中选择“Android 7.1.1(Nougat)”

  3. 等待SDK下载安装完毕,重新编译工程,选择菜单Build > Rebuild Project 即可。如果编译过程出现问题,需要修改AndroidStudio配置,请参考下一章节的内容。

配置AndroidStudio:

推荐使用AndroidStudio 2.X.X版本,如2.3.1。推荐理由:版本相对稳定,下载插件时不会出现后续版本的各种问题,各版本在功能方面实际上差不多。

  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/目录下是否有所设置的版本(可在浏览器中打开两个网址查看)。

    • 打开\gradle\wrapper目录下的gradle-wrapper.properties,设置Gradle版本。

    • 打开工程目录下的build.gradle,设置Plugin版本。

  2. 设置Android SDK版本。

    • 可以打开app目录下的build.gradle根据需要修改SDK版本号。

    • SDK版本号修改后需要注意是否已安装对应版本的Android SDK,可以在File > Settings > Android SDK > SDK Platforms中查看并下载。

  3. 代理配置。

    • 打开File > Settings > HTTP Proxy设置好相关配置即可(如下图所示)。如果不需要使用代理,请选择No proxy。

    • 打开工程目录下的gradle.properties,设置工程的http和https代理配置(一般两个配置是一样的)。

初始化

在发起业务前,需要先初始化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联接管理平台时需要进行绑定操作,从而将设备或网关与平台进行关联。开发者通过传入设备序列号以及设备信息,将设备或网关绑定到物联网平台。

设备或网关绑定成功后或重启后,需要进行登录的流程,在设备或网关成功登录物联网平台后,才可以进行其它服务操作,比如接入其他传感器,数据上报等等。如果设备或网关登录成功,那么设备或网关在平台的状态显示为已在线。

  1. 修改绑定参数。

    绑定时使用的设备固有信息(如设备型号等)是从“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

  2. 绑定设备。

    调用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函数的处理。

  3. 配置登录参数。

    登录前需要通过参数配置接口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");
    }
    

  4. 设备登录。

    注册广播接收器对设备登录结果进行相应处理。

    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();
    }
    

编译安装程序

绑定和登录功能完成后,可以先测试一下网关是否能正常与平台对接,再进行后续功能开发。

  1. 将Android设备连到计算机上,点击按钮编译安装工程到Android设备上。

  2. 在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”

  1. 登录开发中心,创建一个项目,在该项目空间内,选择产品 > 产品开发,点击“新建产品”

  2. “创建产品”中,选择“本地导入产品创建”,单击“上传Profile”上传“Gateway_Huawei_AgentLite01.zip”“Motion_Huawei_test01.zip”

  3. 选择产品 > 设备管理,单击“添加真实设备”,进入“新建增实设备”页面。

  4. 根据向导注册设备。

    1. 选择产品。

      产品:AgentLite001

    2. 填写设备相关信息,单击“确定”
      • 设备名称:AgentLiteDevice
      • 设备标识:aaa123456,需要与AgentLiteDemo中网关的设备标识一致。
      • 接入方式:网关(Agentlite)

设备上线

  1. 点击AgentLiteDemo上的“BIND”按钮,查看界面上打印出的“设备日志”

  2. 当出现“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.dataReportDataTransService. mqttDataPub接口进行数据上报,各个参数使用非直连设备的相关数据即可,此处不再复述。

设备数据上报成功后,可以在非直连设备的“历史数据”中查看上报的数据。

相关文档