物联网开发平台 Android 智能设备(设备动态注册)

这篇将介绍如何在 Android 平台基于腾讯云物联网设备端 Android SDK,使用动态注册(Dynamic Register)能力,在产品量产阶段由设备自动从云端获取设备密钥,减少客户手动逐个烧录设备密钥的工作量,提升量产效率。

相关产品
物联网开发平台 产品页,含版本规格、价格与购买入口。

一、关键概念

动态注册用于产品量产过程中,在控制台批量创建设备后,设备根据 productId、productSecret、deviceId,从后台获取设备密钥(deviceSecret)。该机制减少客户手动逐个烧录设备密钥的工作量,提升量产效率。

二、适用场景

·量产阶段需要批量激活大量设备,逐一烧录设备密钥成本过高。

·设备出厂时只烧录产品级别的 productSecret,由设备首次联网时自行换取设备密钥。

·设备端希望密钥不固化在产线,降低密钥泄漏风险。

三、名词解释

名词 说明
productId 产品标识,在控制台创建产品时生成。
productSecret 产品密钥,产品级别,用于动态注册时对请求进行 HMAC-SHA256 签名与对响应进行 AES-128-CBC 解密。
deviceId 设备名称,在控制台批量创建设备时由平台生成或自定义,需与控制台保持一致。
deviceSecret 设备密钥,动态注册成功后由云端下发,后续登录时使用。

四、前提条件

在接入动态注册功能前,请你先完成以下准备工作:

1. 登录 物联网开发平台控制台,创建产品并记录 productId 与 productSecret。

2. 在控制台批量创建设备,记录每台设备的 deviceId。动态注册要求设备名必须先在控制台预创建,否则会返回 Pre create mode: device not exists。

3. 在产品详情页开启动态注册功能。如果未开启,设备端会收到 Not support dynamic device register, please check setting first。

4. 已完成 SDK 初始化(initSDK)流程。动态注册仅需 SDK 初始化,不依赖登录成功。

五、接入步骤

本节介绍如何调用 SDK 完成动态注册的核心调用:初始化 SDK、发起注册请求、在回调中获取设备密钥、使用密钥完成登录。

六、步骤 1:控制台预创建设备并开启动态注册

1. 登录 物联网开发平台控制台,在产品列表中单击创建的产品名称进入详情。

2. 在设备页面单击批量新建设备,生成若干 deviceId。动态注册时传入的 deviceId 必须在此列表中存在。

3. 在产品详情页的动态注册开关处,确认功能已开启。关闭状态下注册请求会被云端拒绝。

七、步骤 2:初始化 SDK

调用 initSDK 完成 SDK 初始化,动态注册依赖 SDK 内部的 HTTP/TLS 能力。初始化成功返回 0(TXIoTError.SUCCESS)。

TXIoTDeviceEngine.Config config = new TXIoTDeviceEngine.Config();config.storagePath = getFilesDir().getAbsolutePath();config.logLevel = TXIoTDeviceEngine.LogLevel.INFO;int ret = TXIoTDeviceEngine.getInstance(applicationContext).initSDK(config);if (ret != TXIoTError.SUCCESS) { Log.e(TAG, "initSDK failed: " + ret); return;}

八、步骤 3:发起动态注册请求

调用 dynamicRegister 发起注册,入参 DynamicRegisterParams:

字段 说明
productId 产品标识,必填。
deviceId 设备名称,必填,需在控制台预创建。
productSecret 产品密钥,必填,长度需 ≥ 16字节(AES-128 密钥长度要求)。

回调 TXIoTValueCallback<String> 参数说明:

回调 说明
onSuccess(String deviceKey) 注册成功,deviceKey 为云端下发的设备密钥,后续登录时作为 deviceSecret 使用。
onError(int code, String desc) 注册失败,code 为错误码,desc 为错误描述。常见错误码详见 常见问题。

注意:说明:

TXIoTDeviceEngine.DynamicRegisterParams params = new TXIoTDeviceEngine.DynamicRegisterParams();params.productId = "YOUR_PRODUCT_ID";params.deviceId = "YOUR_DEVICE_ID";params.productSecret = "YOUR_PRODUCT_SECRET";TXIoTDeviceEngine.getInstance(applicationContext).dynamicRegister(params, new TXIoTValueCallback<String>() { @Override public void onSuccess(String deviceKey) { Log.i(TAG, "dynamic register success, deviceKey=" + deviceKey); // 见步骤 4:使用该密钥登录 } @Override public void onError(int code, String desc) { Log.e(TAG, "dynamic register failed: " + code + ", " + desc); }});

九、步骤 4:使用获取的密钥登录

动态注册成功后,在回调中拿到 deviceKey,将其作为 deviceSecret 调用 login 完成登录。建议将密钥持久化到本地存储,避免每次开机都重新注册。

@Overridepublic void onSuccess(String deviceKey) { Log.i(TAG, "dynamic register success, deviceKey=" + deviceKey); // 建议持久化 deviceKey,下次开机直接复用,无需再次动态注册 // saveDeviceSecretToStorage(deviceKey); TXIoTDeviceEngine.DeviceInfo deviceInfo = new TXIoTDeviceEngine.DeviceInfo(); deviceInfo.productId = "YOUR_PRODUCT_ID"; deviceInfo.deviceId = "YOUR_DEVICE_ID"; deviceInfo.deviceSecret = deviceKey; // 使用动态注册获取的密钥 TXIoTDeviceEngine.getInstance(applicationContext).login(deviceInfo, new TXIoTCallback() { @Override public void onSuccess() { Log.i(TAG, "login success"); } @Override public void onError(int code, String desc) { Log.e(TAG, "login failed: " + code + ", " + desc); } });}

注意:deviceKey 属于设备敏感凭证,建议持久化到应用私有目录或 Android Keystore 等安全存储中,避免明文保存或提交到代码仓库。

十、完整示例代码

以下示例整合上述步骤,演示在 Android 应用中完成 SDK 初始化、动态注册、并使用获取的密钥登录的完整流程。

package com.example.iotdemo;import android.content.Context;import android.util.Log;import com.tencent.liteav.iot.TXIoTCallback;import com.tencent.liteav.iot.TXIoTDeviceEngine;import com.tencent.liteav.iot.TXIoTError;import com.tencent.liteav.iot.TXIoTValueCallback;public class DynamicRegisterHelper { private static final String TAG = "DynamicRegister"; private final TXIoTDeviceEngine mEngine; private final String mProductId; private final String mDeviceId; private final String mProductSecret; public DynamicRegisterHelper(Context context, String productId, String deviceId, String productSecret) { mEngine = TXIoTDeviceEngine.getInstance(context.getApplicationContext()); mProductId = productId; mDeviceId = deviceId; mProductSecret = productSecret; } /** 初始化 SDK 并开始动态注册 */ public void start() { // 1. 初始化 SDK TXIoTDeviceEngine.Config config = new TXIoTDeviceEngine.Config(); config.logLevel = TXIoTDeviceEngine.LogLevel.INFO; int ret = mEngine.initSDK(config); if (ret != TXIoTError.SUCCESS) { Log.e(TAG, "initSDK failed: " + ret); return; } // 2. 发起动态注册 TXIoTDeviceEngine.DynamicRegisterParams params = new TXIoTDeviceEngine.DynamicRegisterParams(); params.productId = mProductId; params.deviceId = mDeviceId; params.productSecret = mProductSecret; mEngine.dynamicRegister(params, new TXIoTValueCallback<String>() { @Override public void onSuccess(String deviceKey) { Log.i(TAG, "dynamic register success, deviceKey=" + deviceKey); loginWithDeviceKey(deviceKey); } @Override public void onError(int code, String desc) { Log.e(TAG, "dynamic register failed: " + code + ", " + desc); } }); } /** 3. 使用动态注册获取的密钥登录 */ private void loginWithDeviceKey(String deviceKey) { // 建议持久化 deviceKey,下次开机直接复用,无需再次动态注册 // saveDeviceSecretToStorage(deviceKey); TXIoTDeviceEngine.DeviceInfo deviceInfo = new TXIoTDeviceEngine.DeviceInfo(); deviceInfo.productId = mProductId; deviceInfo.deviceId = mDeviceId; deviceInfo.deviceSecret = deviceKey; mEngine.login(deviceInfo, new TXIoTCallback() { @Override public void onSuccess() { Log.i(TAG, "login success"); } @Override public void onError(int code, String desc) { Log.e(TAG, "login failed: " + code + ", " + desc); } }); } /** 4. 业务完成后释放资源 */ public void release() { mEngine.logout(null); mEngine.uninitSDK(); }}

注意:说明:

注意:1. 动态注册仅依赖 initSDK 成功,无需提前登录;获取到 deviceKey 后再执行 login。

注意:2. Demo 的 LoginActivity 已集成动态注册流程,可参考其实现。

十一、编译并运行

Demo 已开源,仓库地址:github.com/Tencent-RTC/Tencent_IoT_Device,Android Demo 位于顶层 Android/ 目录。

1. 使用 git clone 将开源 Demo 从 GitHub 克隆到本地。

2. 打开 Android Studio,点击 Open 导入工程,等待 Gradle Sync 完成。

3. 连接 Android 真机,点击工具栏 Run 编译运行。

# 也可在控制台打包 APK 后发送到手机安装./gradlew :app:assembleDebug

4. 观察日志输出,出现以下内容代表动态注册与登录均成功。

dynamic register success, deviceKey=xxxxxxxxxxxxxlogin success

十二、常见问题

现象 排查建议
动态注册回调提示 Not support dynamic device register, please check setting first。 动态注册功能未在控制台开启。请在产品详情页打开动态注册开关后再试。
动态注册回调提示 Pre create mode: device not exists。 传入的 deviceId 在控制台未预创建。请先在控制台批量创建对应设备,确保 deviceId 与控制台一致。
动态注册回调提示 Device has been activated。 该设备已动态注册过且密钥已激活。已注册的设备名再次动态注册会被拒绝,请使用上次获取的密钥登录。
动态注册获取的密钥未登录,再次注册拿到新密钥。 如果动态注册获取的密钥未用于登录,下次仍可执行动态注册,但会获取到新的密钥,之前的密钥同时失效,只能使用最新获取的密钥。
dynamicRegister 返回 DYNAMIC_REGISTER_BUSY(-20) 上一次注册请求仍在途。SDK 同一时刻只允许一个注册请求,请等待回调返回后再发起新请求。
dynamicRegister 返回 INVALID_ARGUMENT(-3) 检查 productId、deviceId 是否为空或过长;productSecret 长度是否 ≥ 16字节(AES-128 密钥要求)。
dynamicRegister 返回 NOT_INITIALIZED(-4) 确认在调用前已成功调用 initSDK。
DYNAMIC_REGISTER_REQUEST_FAILED(-21) HTTP 请求失败或云端返回错误。请检查网络、productSecret 是否正确、签名是否匹配;查看日志中的错误描述获取具体原因。
DYNAMIC_REGISTER_RESPONSE_INVALID(-22) 云端响应格式异常或解密失败。常见原因为 productSecret 与控制台不一致(解密失败),或响应被中间代理改写。

十三、联系我们

如果你在接入或使用过程中有任何疑问或者建议,欢迎 联系我们 提交反馈。

赞 (0)
上一篇 4天前
下一篇 4天前