Skip to content

Android SDK2.0.X开发文档

概述

App 开发之前请先申请相关账号:

  • 申请第三方平台登录账号,目前支持 QQ,微信,微博,Google,Twitter,Facebook。如果不需要第三方登录,可以不用申请
  • 申请个推账号。如果不需要推送,可以不用申请
  • 申请Hekr平台企业账号,并完善相关信息

开发准备

使用SDK开发之前请务必通读本文档

集成准备

1、下载SDK配置文件

2、快速导入SDK

  • 请确保您下载或引用的是最新的SDK版本

1.core模块:这是SDK的主要部分,必须要引入

Gradle:

compile 'me.hekr.sdk:core:x.x.x'

Maven:

<dependency>
  <groupId>me.hekr.sdk</groupId>
  <artifactId>core</artifactId>
  <version>x.x.x</version>
  <type>pom</type>
</dependency>

core模块最新版本: Download

AndroidManifest.xml 权限

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

2.config模块:如果App需要给设备配网,请引入config模块 Gradle:

compile 'me.hekr.sdk:config:x.x.x'

Maven:

<dependency>
  <groupId>me.hekr.sdk</groupId>
  <artifactId>config</artifactId>
  <version>x.x.x</version>
  <type>pom</type>
</dependency>

config模块最新版本: Download

3.web模块:如果需要使用H5设备控制功能,请引入web模块

compile 'me.hekr.sdk:web:x.x.x'

Maven:

<dependency>
  <groupId>me.hekr.sdk</groupId>
  <artifactId>web</artifactId>
  <version>x.x.x</version>
  <type>pom</type>
</dependency>

web模块最新版本: Download

当你引入web模块时,由于我们使用了CrossWalk开源项目,所以必须在项目根目录下的gradle文件中加入Crosswalk的Maven仓库

allprojects {
    repositories {
        maven {
            url 'https://download.01.org/crosswalk/releases/crosswalk/android/maven2'
        }
    }
}

在项目的gralde文件中加入

ndk {
    abiFilters "armeabi-v7a"
}

AndroidManifest.xml 权限

    <uses-permission android:name="android.permission.VIBRATE" />

一、配置

  • 说明:本SDK中已使用以下依赖,请勿重复配置!
// 只在web模块中使用,如果不引用web模块,那么xwalk_core_library不会被依赖
org.xwalk:xwalk_core_library:23.53.589.4
// 以下三个在引入core模块时被依赖
org.jmdns:jmdns:3.5.1
com.neovisionaries:nv-websocket-client:2.2
netty-all-4.1.9.Final.jar
  • 如果引入本SDK时发生引用资源冲突,请在项目的gradle的dependencies依赖中,exclude相关冲突的包。如:
// 排除一个依赖
compile('me.hekr.sdk:core:x.x.x'){
    exclude group: 'org.jmdns', module: 'jmdns'
}
// 或者需要排除多个依赖
compile('me.hekr.sdk:core:x.x.x'){
    exclude(group: 'org.jmdns', module: 'jmdns')
    exclude(group: 'com.neovisionaries', module: 'nv-websocket-client')
}
compile('me.hekr.sdk:web:x.x.x'){
    exclude group: 'org.xwalk', module: 'xwalk_core_library'
}
  • 在项目res目录下创建raw目录,将下载包中的config.json复制进去,config.json为项目的配置文件和第三方登录配置文件(填写各大平台申请的参数)。
  • config.json文件配置说明:文件格式不可变,pid为在氦氪console平台 注册企业开发者后在个人中心->认证信息中相应的企业pid,配置文件中其他第三方登录数据在各大第三方平台申请填写,如不需要使用某些第三方登录则在相应位置留空即可。
"Hekr": {
    "AppId": "xxxxxx"
}

配置文件中Hekr之下AppId:氦氪console平台的pid,登录氦氪console平台之后可在右上角个人中心查看。
配置文件中的Social、push为第三方登录、个推推送平台信息,如不需要置""即可。
  • 如果需要第三方微信登录,则必须将下载包中的wxapi文件夹复制项目包名目录(微信开放平台填写的包名)下!【具体参考微信开放平台文档
  • 请在氦氪console平台申请App定制开发。

1.1、在开始使用前进行SDK的初始化工作

// 初始化SDK
HekrSDK.init(this, R.raw.config);
// 是否开启日志,默认开启
HekrSDK.enableDebug(true);

二、全球化配置

Hekr云支持全球化访问和控制设备,为了获得良好的网络体验,在使用api之前必须先获取app(用户)最近的服务中心信息,并由此调用对应数据中心的api。 获取数据中心信息的服务由 info.hekr.me:91 统一提供服务,同时也提供了设备查询信息,都是通过 tCP 方式获取的。具体获取方法请查询APP通信

如果没有全球化需求,只在中国地区用,那么就可以不进行上述操作,SDK中所以的地址和域名都会是默认的。当准备使用全球化功能时,最好能够在请求任何Hekr接口之前获取对应的数据中心的相关信息。

【注意】当通过TCP连接获取了域名(Domain)之后,基础请求地址需要更改为相应的域名。其中有3个需要修改(每个在此地址基础上的请求接口都需要修改,最好做法是将这3个地址提取为全局变量),分别如下:

例如,如果获取到的域名是hekrus.me,那么需要将上述3个地址修改如下:

另外,在获取域名之后,也需要更新SDK中的请求地址,具体操作如下:

// domian是通过上述TCP获取到的域名(domain字段)
HekrSDK.setOnlineSite(domain);

三、用户接口

氦氪用户接口包括了登录等部分。开发者需要先通过1.1和1.2正确初始化SDK后进行操作,用户注册等功能详见云端API。

3.1、用户登录

Hekr.getHekrUser().login(username, password, callback);

参数

key 类型及范围 说明
userName String 用户名
passWord String 用户密码
callback HekrCallback 登录后的回调

示例code

import me.hekr.sdk.Hekr;
import me.hekr.sdk.HekrSDK;
import me.hekr.sdk.inter.HekrCallback;

Hekr.getHekrUser().login("xxxxxxxxxxx", "xxxxxx", new HekrCallback() {
    @Override
    public void onSuccess() {
        Log.d(TAG, "Success");
    }

    @Override
    public void onError(int errorCode, String errorMsg) {

    }
});

3.2、当前用户token

当用户登录以后,可以通过SDK获取

SDK示例code(调用此接口前用户必须登录成功)

// 获取user Id
String userId = Hekr.getHekrUser().getUserId();
// 获取登录后的token
String accessToken = Hekr.getHekrUser().getToken();
// token失效后刷新
Hekr.getHekrUser().refreshToken(callback);

如果刷新失败,那么需要用户去重新登录

3.3、登出

SDK示例code

// 用户登出
Hekr.getHekrUser().logout(callback);
key 类型及范围 说明
callback HekrCallback 回调

四、设备配网

配网说明:仅适用于氦氪固件4.1.22.1及以上版本 配网意义:

  • 设备接入氦氪云
  • 将设备与账号进行绑定

4.1、区分设备配网类型

  1. 获取厂家所有产品

  2. 根据bindtype字段区分不同产品的配网方式

  • WIFI (带有氦氪WIFI模块的设备)

  • QRSCAN(网关设备)

  • ZIG_BEE(网关子设备)

4.2、WIFI设备配网流程

WIFI设备配网方式 1.udp发包配网 2.ap模式配网(可做为第一种失败后的兼容方式)

1、App获取PINCode

2、App将ssid、pwd、PINCode采用UDP协议发送至模块

3、App在做第二步的同时,获取当前局域网设备直至配网结束

4.2.1、WIFI设备SmartConfig配网

操作说明:请让模块处于配网模式

private INewConfig config;

/**
 * 开始配网
 */
private void config(){
    config = Hekr.getHekrConfig().getNewConfig(ConfigType.COMMON_DEV);
    config.startConfig(this, getConfiguation(), new ConfigCallback());
}

private Map<String, String> getConfiguation() {
    HashMap<String, String> configuration = new HashMap<>();
    // 路由器的SSID
    configuration.put("ssid", "xxxxxx");
    // 路由器的密码
    configuration.put("password", "xxxxxx");
    // 获取的PinCode
    configuration.put("pinCode", "xxxxxx");
    return configuration;
}

private class ConfigCallback implements HekrConfigCallback {

    @Override
    public void onStart() {
        // 配网开始
    }

    @Override
    public void onAdd(ConfigDevice device) {
        // 配网时发现新的设备,注意这里同一个设备每次回调的对象都是同一个,只是状态有所更改,不要直接对这个对象的属性进行更改
    }

    @Override
    public void onUpdate(ConfigDevice device) {
        // 配网时设备状态更新,注意这里同一个设备每次回调的对象都是同一个,只是状态有所更改,不要直接对这个对象的属性进行更改
    }

    @Override
    public void onResult(List<ConfigDevice> result) {
        // 调用stopConfigSafely时返回配网结束时的设备最终状态,直接调用stop不会有这个回调
    }

    @Override
    public void onStop() {
        // 结束配网的回调
    }

    @Override
    public void onError() {
        // 配网错误
    }
}

// WIFI设备SmartConfig停止配网
config.stopConfig();

4.2.2、WIFI设备兼容模式配网

操作说明:请让模块处于兼容模式,同时让手机连接到设备的SoftAP,设备的AP以SmartDeivce开头。在配网过程中,由于手机会切换连接的AP,所以很大概率会收不到局域网消息。

/**
 * 开始配网
 */
private void configAP(){
    config = Hekr.getHekrConfig().getNewConfig(ConfigType.COMMON_DEV);
    config.startSoftAPConfig(this, getConfiguation(), new ConfigCallback());
}

private Map<String, String> getConfiguation() {
    HashMap<String, String> configuration = new HashMap<>();
    // 路由器的SSID
    configuration.put("ssid", "xxxxxx");
    // 路由器的密码
    configuration.put("password", "xxxxxx");
    // 获取的PinCode
    configuration.put("pinCode", "xxxxxx");
    return configuration;
}

private class ConfigCallback implements HekrConfigCallback {

    @Override
    public void onStart() {
        // 配网开始
    }

    @Override
    public void onAdd(ConfigDevice device) {
        // 配网时发现新的设备
    }

    @Override
    public void onUpdate(ConfigDevice device) {
        // 设备时设备状态更新
    }

    @Override
    public void onResult(List<ConfigDevice> result) {
        // 调用stopConfigSafely时返回配网结束时的设备最终状态,直接调用stop不会有这个回调
    }

    @Override
    public void onStop() {
        // 结束配网的回调
    }

    @Override
    public void onError() {
        // 配网错误
    }
}

// WIFI设备兼容模式停止配网
config.stopConfig();

4.3、网关设备扫码配网

网关设备二维码生成:氦氪console平台的网关设备批量生成

4.3.1、扫描设备上所贴二维码(扫码自行实现)

4.3.2、解析返回字符串(获取配网所需devtid,bindKey)

public static HashMap<String, String> urlSplit(String url) {
        HashMap<String, String> hashMap = new HashMap<>();
        if (!TextUtils.isEmpty(url) && url.contains("?") && url.contains("&") && url.contains("=")) {
            String str = url.substring(url.indexOf("?") + 1, url.length());
            String cookieParams[] = str.split("&");

            if (cookieParams.length > 0) {
                for (String cookieParam : cookieParams) {
                    String kvParam[] = cookieParam.split("=");

                    if (kvParam.length == 2) {
                        hashMap.put(kvParam[0].trim(), kvParam[1].trim());
                    }
                }
            }
            return hashMap;
        } else {
            return null;
        }
    }

// 解析出来后获取devTid和bindKey
String devTid;
String bindKey;
if (hashMap != null && hashMap.containsKey("action")) {
    switch (hashMap.get("action")) {
        case "bind":
            if (!TextUtils.isEmpty(hashMap.get("devTid")) &&
                    !TextUtils.isEmpty(hashMap.get("bindKey"))) {
                devTid = hashMap.get("devTid")
                bindKey = hashMap.get("bindKey");
                break;
                default:
                    break;

            }
    }
}

4.3.3、根据扫码解析的数据,进行设备配网

protected IConfig iConfig;
protected HashMap<String, String> configParam;

configParam = new HashMap<>();
iConfig = Hekr.getHekrConfig().getConfig(ConfigType.GATEWAY_DEV);

configParam.put("devTid",devTid);
configParam.put("bindKey",bindKey);

iConfig.startConfig(ScanAddDeviceActivity.this, configParam, new HekrConfigDeviceListener() {
            @Override
            public void getNewDevice(JSONObject device) {

            }

            @Override
            public void getDeviceSuccess() {

            }

            @Override
            public void getDeviceFail(int error ,String errorMsg) {
                if(error==5400044) {
                // 网关不在线
                }
            }
        });

4.4、网关子设备配网

网关子设备配网前提:当前账号至少有一个网关且该网关在线(确保网关已经连接网线)

获取当前用户下的所有网关

  • 获取所有设备并根据devtype字段筛选出网关设备,devtype字段为GATEWAY的是网关设备

4.4.1、网关子设备配网

protected IConfig iConfig;

iConfig = Hekr.getHekrConfig().getConfig(ConfigType.GATEWAY_SUB_DEV);

protected HashMap<String, String>  configParam = new HashMap<>();

/**
* devTid:网关devTid(子设备即将绑定的网关):网关设备信息中
* ctrlKey:网关ctrlKey:网关设备信息中
* subMid:所需配网的网关子设备mid :厂家所有产品接口中该子设备mid
*/
configParam.put("devTid", xxxx);
configParam.put("ctrlKey", xxxx);
configParam.put("subMid", product.getMid());

if (Hekr.getHekrClient().isOnline()) {
            iConfig.startConfig(GateSubDeviceLinkActivity.this, configParam, new HekrConfigDeviceListener() {
                @Override
                public void getNewDevice(JSONObject device) {
                    // 子设备配网命令返回值
                }

                @Override
                public void getDeviceSuccess() {

                }

                @Override
                public void getDeviceFail(int error, String errorMsg) {
                    // 子设备配网命令返回值
                }
            });
} else {
    // Websocket未链接
}

// 停止网关子设备配网
// 必须主动在getDeviceFail()或者getDeviceSuccess中调用
iConfig.stopConfig();

4.5、WIFI设备配网状态

当有新设备或者设备更新时会返回ConfigDevice对象。ConfigDevice中可以获取到两个状态,一个是currentStatus,一个是errorStatus。状态由ConfigStatus这个枚举类指定。有NONE, GET_SECURITY_CODE, DEVICE_CONNECTED_ROUTER, CLOUD_VERIFY_DEVICE, DEVICE_LOGIN_CLOUD, DEVICE_BIND_SUCCESS这几个状态。

1. NONE:没有状态errorStatus = NONE 表示没有错误
2. GET_SECURITY_CODE:设备获取到安全码(PinCode)
3. DEVICE_CONNECTED_ROUTER:设备连接到路由器
4. CLOUD_VERIFY_DEVICE云端校验设备成功
5. DEVICE_LOGIN_CLOUD设备登录到云端

currentStatus指的是已经正确的步骤,errorStatus指的是错误的步骤。当没有错误时,errorStatus = NONE

currentStatus = DEVICE_BIND_SUCCESS 时或者 errorStatus = DEVICE_BIND_SUCCESS,可以通过

device.getJson();

获取到配网的Json数据,这个json数据中包含了设备配网的信息

4.6、补充说明

配网模式: wifi模块在间隔2秒闪烁表示进入配网模式

新设备定义: App配网过程中,模块处于以下情况App查询到的设备

  • 模块处于配网模式,成功绑定自己本次配网所用账号的设备,判定依据json 属性bindResultCode值为0
  • 模块处于配网模式,但已被别人绑定的设备,判定依据json 属性bindResultCode值为1 属性bindResultMsg值为E001:xxx,xxx即为真正绑定者的账号信息
  • 模块处于配网模式,但模块pk与自定义App配置文件config.json所写Appid(console平台pid)不匹配,判定依据json 属性bindResultCode值为1 属性bindResultMsg值为E003
  • 模块处于配网模式,已被自己账号绑定上并未删除解绑的设备,判定依据json 属性bindResultCode值为1 属性bindResultMsg值为E004

五、设备控制(Android Native)

控制先决条件:用户登录成功

5.1 全球化功能中配置应用需要连接的数据中心

为了提升用户体验,SDK会根据设备所在的数据中心,创建相应数据中心的WebSocket,所以在刷新设备列表以后,需要提取所有设备的dcInfo,然后获取里面的connectHost集合,设置到SDK中。

// list是获取到的设备列表
private void refreshCloudChannels(List<DeviceBean> list) {
        // 使用集合Set,因为设备的host可能会有重复
        Set<String> hosts = new HashSet<>();
        for (DeviceBean bean : list) {
            // dcInfo信息
            DCInfoBean info = bean.getDcInfo();
            // 这里最好做一些非空判断,如果没有的话,设置为默认值
            String host = getHost(info);
            hosts.add(host);
        }
        if (hosts.size() != 0) {
            // 刷新SDK中连接的WebSocket通道
            Hekr.getHekrClient().setHosts(hosts);
        }
    }

/**
 * 通过DCInfoBean获取设备连接的host信息
 */
public static String getHost(DCInfoBean dc) {
        if (dc != null) {
            if (!TextUtils.isEmpty(dc.getConnectHost())) {
                return dc.getConnectHost();
            } else {
                return getDefaultHost();
            }
        }
        return getDefaultHost();
    }

/**
 * 获取默认的host
 */
private static String getDefaultHost() {
        return CloudHostType.HOST_DEFAULT.toString();
    }

5.2、发送控制命令

Json48透传协议:App下发数据->云端->模块->单片机

Json主控协议:[App下发数据->云端->模块(含特殊外围电路直接响应)][402]

5.2.1 发送消息

48透传数据示例:480E02010201000000000000005C 具体设计在氦氪console平台

Json主控数据示例:"{\"R\":0,\"G\":255,\"B\":89,\"W\":0,\"bright\":1,\"cmdId\":1}" 具体设计在氦氪console平台

新增如下使用方法

请求参数

key 类型及范围 说明
message JSONObject 设备控制命令
callback HekrMsgCallback 命令发送回调

示例code

private void sendMessage(){
    String command="{\"action\": \"appSend\",\"params\": {\"devTid\": \"xxxxxx\", \"ctrlKey\": \"xxxxxx\", \"data\": {\"raw\": \"48xxxxxxx\"}}}";
    try {
        JSONObject object = new JSONObject(command);
        Hekr.getHekrClient().sendMessage(object, new HekrMsgCallback() {
            @Override
            public void onReceived(String msg) {
                // 收到云端返回的消息
            }

            @Override
            public void onTimeout() {
                // 发送消息超时
            }

            @Override
            public void onError(int errorCode, String message) {
                // 发送消息错误
            }
        });
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

回调返回值

{
  "msgId" : xxx,
  "action" : "appSendResp",
  "code" : 200,
  "desc" : "xxx",
  "params" : {
    "devTid" : "xxxxxxx",
    "ctrlKey" : "xxxxxxxxxx",
    "appTid" : "xxxxxxxx",
    "data" : {
      "raw" : "48xxxxx"
    }
  }
}

5.2.2 全球化功能中发送消息

全球化时,对应的控制信息需要送设备所在的数据中心,所以发送消息时,需要添加host字段。

请求参数

key 类型及范围 说明
message JSONObject 设备控制命令
callback HekrMsgCallback 命令发送回调
host String 需要发送到哪一个数据中心,需要通过设备信息中额dcInfo中的connectHost字段获取

示例code

private void sendMessage(){
    String command="{\"action\": \"appSend\",\"params\": {\"devTid\": \"xxxxxx\", \"ctrlKey\": \"xxxxxx\", \"data\": {\"raw\": \"48xxxxxxx\"}}}";
    // host 需要通过设备信息中额dcInfo中的connectHost字段获取
    Strig host = "hub.hekr.me";
    try {
        JSONObject object = new JSONObject(command);
        Hekr.getHekrClient().sendMessage(object, new HekrMsgCallback() {
            @Override
            public void onReceived(String msg) {
                // 收到云端返回的消息
            }

            @Override
            public void onTimeout() {
                // 发送消息超时
            }

            @Override
            public void onError(int errorCode, String message) {
                // 发送消息错误
            }
        }, host);

    } catch (JSONException e) {
        e.printStackTrace();
    }
}

5.2.3 App返回帧错误表

App发送命令之后收到的返回帧 说明
{"msgId":4,"action":"errorResp","code":1400006,"desc":"Field cmdId not exist"} App未按照氦氪console平台所填写的模板发送数据。
{"msgId":4,"action":"appSendResp","code":2000115,"desc":"uart timeout"} MCU未在收到模块数据后3秒内回复模块数据。
正确做法:3秒内回复数据。

MCU回复模块的数据中帧序号、帧类型是错的。
正确做法:应该和模块发的帧类型、帧序号一致。

MCU回复模块的数据中检验码出错。
正确做法:发送正确的检验码。

5.3、主动接收设备上报控制命令

设备上报数据->模块->云端->App

5.3.1 主动接收消息

请求参数

key 类型及范围 说明
filter MessageFilter 消息过滤器
dataReceiverListener HekrMsgCallback 数据接收回调接口

回调函数

void onReceived(String message);
void onError(int errorCode, String message);
params 说明
message 符合条件的协议 参考协议

示例code

/**
 * 主动接收消息
 */
private void receiveMessage() {
    try {
        JSONObject filterObject = new JSONObject();
        JSONObject params = new JSONObject();
        params.put("devTid", "xxxxxxxx");
        filterObject.put("params", params);
        filter = new MessageFilter(filterObject);
        Hekr.getHekrClient().receiveMessage(filter, new HekrMsgCallback() {
            @Override
            public void onReceived(String msg) {
                // 收到消息
            }

            @Override
            public void onTimeout() {
                // 超时
            }

            @Override
            public void onError(int errorCode, String message) {
                // 接收错误
            }
        });

    } catch (JSONException e) {
        e.printStackTrace();
    }
}

/**
 * 取消接收
 */
private void deceiveMessage() {
    // 主动接收消息后,如果想取消接收,必须调用这个方法,不然会造成内存泄漏
    if (filter != null) {
        Hekr.getHekrClient().deceiveMessage(filter);
        filter = null;
    }
}

5.4、云端返回所有协议信息

作用:接收云端所有协议信息(例如appResp、devSend、appLoginResp等等动作信息),便于后续自行开发处理。

示例code

/**
 * 主动接收消息
 */
private void receiveAllMessage() {
    filter = new IMessageFilter() {
        @Override
        public boolean doFilter(String in) {
            return true;
        }
    };
    Hekr.getHekrClient().receiveMessage(filter, new HekrMsgCallback() {
        @Override
        public void onReceived(String msg) {
            // 收到消息
        }

        @Override
        public void onTimeout() {
            // 主动接受不会有这个回调
        }

        @Override
        public void onError(int errorCode, String message) {
            // 接收错误
        }
    });
}

六、设备控制(Android Web)

控制先决条件:用户登录成功

6.1、接入指南

// 获取一个实例
IHekrWebClient hekrWeb = Hekr.getHekrWeb().createWebClient();
// 初始化web页面
hekrWeb.init(this, layout, hekrWebBeanpushMessageuseCache);
// 加载页面
hekrWeb.load();

参数:

key 类型及范围 说明
webInterface HekrWebInterface Activity或者Fragment需要实现的接口
hekrWebBean HekrWebBean 传入的设备数据
pushMessage String 推送消息预留入口,置空即可
useCache boolean 是否采用webView页面缓存机制,true:首次打开该页面将自动下载控制页面zip包至手机SD卡

示例code

public class WebActivity extends AppCompatActivity implements HekrWebInterface {

    private IHekrWebClient mHekrWeb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);
        FrameLayout layout = (FrameLayout) findViewById(R.id.layout_web);
        // 创建一个Web Client
        mHekrWeb = Hekr.getHekrWeb().createWebClient();
        // 设置页面的监听
        mHekrWeb.setWebActionListener(new MyWebViewPageStatusListener());
        // 设置页面必须的信息
        HekrWebBean hekrWebBean = getHekrWebBean();
        mHekrWeb.init(this, layout, hekrWebBean, "", true);
        // 加载
        mHekrWeb.load();
    }

    private HekrWebBean getHekrWebBean() {
        HekrWebBean hekrWebBean = new HekrWebBean();
        // 设置H5页面的下载地址
        hekrWebBean.setH5Zip("xxxxxxxx");
        // 设置H5页面的地址
        hekrWebBean.setH5Url("xxxxxxxx");
        // 设置CtrlKey
        hekrWebBean.setCtrlKey("xxxxxxxx");
        // 设置产品公共秘钥
        hekrWebBean.setPpk("xxxxxxxx");
        // 设置为独立设备
        hekrWebBean.setType(DeviceType.DEVICE_INDEPENDENT);
        // 设备DevTid
        hekrWebBean.setDevTid("xxxxxxxx");
        // 设备信息,从云端API获取的设备json字符串
        hekrWebBean.setDeviceInfo("xxxxxxxx");
        // 如果需要全球化,那么需要添加如下字段
        // 设置设备需要连接到的数据中心,如:hub.hekr.me
        // 获取的设备信息中有dcInfo信息,信息中可以获取connectHost字段,这个字段就是所需的
        hekrWebBean.setHost(host);
        // 设置前端请求接口要用到的域名,如:hekr.me
        hekrWebBean.setDomain(domain);

        return hekrWebBean;
    }

    @Override
    public Context getContext() {
        return this;
    }

    @Override
    public void onFinish() {
        finish();
    }

    /**
     * 对SDK中页面的监听,如果不想实现这些接口,可以用封装的抽象类DefaultWebActionListener
     */
    private class MyWebViewPageStatusListener implements HekrWebActionListener {

        @Override
        public void onPageStarted(String url) {
            // 页面加载开始
        }

        @Override
        public void onPageError(int errorCode, String description) {
            // 页面加载错误
        }

        @Override
        public void onPageFinished(String url) {
            // 页面加载完成
        }

        @Override
        public void onAllPageClosed() {
            finish();
        }

        @Override
        public void openScan(int requestCode) {

        }

        @Override
        public void openFingerPrint(int requestCode) {

        }

        @Override
        public void takePhoto(String key) {

        }

        @Override
        public void onProgressChanged(int progressInPercent) {
            // 加载进度
        }

        @Override
        public void onGetBackgroundColor(String s) {

        }
    }

    /**
     * 返回键处理
     */
    @Override
    public void onBackPressed() {
        if (mHekrWeb != null) {
            mHekrWeb.notifyBackPressed();
        } else {
            finish();
        }
    }

    /**
     * 当页面销毁时,销毁H5页面
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mHekrWeb != null) {
            mHekrWeb.destroy();
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="me.hekr.sdkdemo.WebActivity">

    <FrameLayout
        android:id="@+id/layout_web"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.constraint.ConstraintLayout>

Web控制页面开发JS指南

七、混淆设置

core模块需要添加混淆规则

# Netty
-keep class io.netty.** {*;}
-dontwarn io.netty.**

web模块中需要添加混淆

# Crosswalk
-keep class org.xwalk.core.**{*;}
-keep class org.chromium.** {*;}
-keepattributes ** 

八、错误码使用说明

Hekr SDK中可以直接通过errorCode获取到对应的errorMessage

String errorMsg = ErrorCodeUtil.getErrorDesc(code);
errorCode 说明
11001 消息格式错误
11002 消息内容为空
11003 发送消息时App ID为空
11004 消息json字符串中没有params参数
11005 发送消息时没有连接
12001 网络错误
13001 局域网连接失败
13002 局域网授权超时
20001 没有发现配网设备
30001 网页加载错误

其他具体错误码参见API文档

错误码表

九、 常见问题

SDK打印的错误日志中出现错误码8400000

氦氪console平台上所创建产品的ProKey(产品密钥)与采购模块中烧录的ProKey不一致

设备无法成功配网

  • 使用SDK配网前还未调用SDK用户登录
  • 连接的wifi应该为2.4G频段而不是5G频段
  • 传入的wifi名称与wifi密码不对,例如实际名称多了双引号
  • 用户token过期并未做刷新token或让用户重新登录处理,导致配网时的pinCode实际已经处于失效状态
  • 设备未进入配网模式。配网模式:模块指示灯为亮 1s、灭 1s