# RegisterMiniProgramDevice

> 建议使用 [WMPFMiniProgramDeviceApi.registerMiniProgramDevice](/doc/oplatform/Miniprogram_Frame/api/cli/miniprogramdevice/registerMiniProgramDevice) 接口.

> 本接口不需要 `ActivateDevice` 即可使用。

接入小程序硬件生态的[设备注册](/miniprogram/dev/framework/device/device-register.md)。

注册设备将 modelId 和 SN 与设备绑定。一旦成功后，除非更换存储芯片，否则 **appId、modelId、sn 均不能更换**。

**WMPF 1.2.0 版本开始支持。**

## 注意事项（**调用前必读**）
- 注册设备成功后，会将 SN 固化至 EMMC/RPMB 分区中，标定此设备的唯一身份。**sn 和 modelId 一经写入后续即不可更改。**
- **此处使用的 SN，必须经过 WMPF 的 addDevice 接口作为 deviceId 注册，并与 WMPF [设备激活](ActivateDevice)时使用的 deviceId 一致。**
- 若 WMPF 缓存被删除重装、清理缓存或 keystone 失效，会报错 `cert fail`。可以清理 APK 的数据再以**相同的 appId、modelId、sn**调用接口重新注册即可。
- 注册过程会有网络请求，时长根据网络情况会有所不同。
- **注册是否成功以返回值里的 `code` 为准**，而不以接口调用是否成功。

## 调用参数

| 属性     | 必填 | 类型   | 说明                                                                                                                                                                    |
|----------|------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| appId    | 是   | string | 小程序 appId                                                                                                                                                            |
| modelId  | 是   | string | [设备接入](/miniprogram/dev/framework/device/device-access.md)时从「小程序管理后台」申请获得的 model_id                                                                                             |
| sn       | 是   | string | 设备序列号。厂商自己生成，长度不能超过 128 字节。字符只接受数字，大小写字母，下划线（*）和连字符（-）。
 **此处使用的 sn 必须与 WMPF 激活设备使用的 deviceId 一致** |
| snTicket | 是   | string | 通过[获取设备票据](/miniprogram/dev/server/API/hardware-device/api_getsnticket.md)接口获得                                                                                                               |

## 返回参数

| 属性   | 类型   | 说明                        |
|--------|--------|-----------------------------|
| code   | int    | 错误码，具体含义参加下表    |
| errMsg | string | 当 code 为 -11 时，错误详情 |

**code 取值**
| code 值 | 描述                             |
|---------|----------------------------------|
| 0       | 成功                             |
| -1      | 参数错误                         |
| -2      | 通用 IO 错误                     |
| -3      | KEY 不匹配                       |
| -4      | 网络请求无回复                   |
| -5      | 权限错误                         |
| -6      | KEY 不可用                       |
| -7      | rpmbd 服务没运行                 |
| -8      | EMMC/UFS 不匹配。里面已经存在 SN |
| -9      | EMMC/UFS IO 错误                 |
| -10     | 密钥不存在                       |
| -11     | 其他异常，异常内容可查看 errMsg  |

## 示例代码

```kotlin
fun registerMiniprogramDevice(appId: String, modelId: String,
                              deviceId: String, snTicket: String): Single<WMPFRegisterMiniProgramDeviceResponse> {
    return Single.create {
        val request = WMPFRegisterMiniProgramDeviceRequest().apply {
            this.baseRequest = WMPFBaseRequestHelper.checked()
            this.appId = appId
            this.modelId = modelId
            this.sn = deviceId
            this.snTicket = snTicket
        }

        val result = WMPFIPCInvoker.invokeAsync<IPCInvokerTask_RegisterMiniProgramDevice, WMPFRegisterMiniProgramDeviceRequest, WMPFRegisterMiniProgramDeviceResponse>(
            request,
            IPCInvokerTask_RegisterMiniProgramDevice::class.java,
            object : IPCInvokeCallbackEx<WMPFRegisterMiniProgramDeviceResponse> {
                override fun onCallback(response: WMPFRegisterMiniProgramDeviceResponse) {
                    if (isSuccess(response)) {
                        // 注意，此处只表示请求完成，应进一步判断 response.code == 0 作为注册成功
                        it.onSuccess(response)
                    } else {
                        it.onError(TaskErrorException(createTaskError(response)))
                    }
                }

                override fun onBridgeNotFound() {
                    it.onError(Exception("bridge not found"))
                }

                override fun onCaughtInvokeException(exception: java.lang.Exception?) {
                    if (exception != null) {
                        it.onError(exception)
                    } else {
                        it.onError(java.lang.Exception("null"))
                    }
                }
            })

        if (!result) {
            it.onError(Exception("invoke registerMiniprogramDevice fail"))
        }
    }
}
```
