本文介绍如何使用腾讯云物联网(IoT)应用端 SDK 的
TXIoTDeviceManager 把一台已绑定设备的使用权授予其他账号,包括生成分享凭据、接受分享、查询与撤销共享关系。设备本身的绑定与解绑,参见 设备绑定;把成员加入家庭以获得家庭下全部设备的权限,参见 家庭管理。说明:
设备分享与设备绑定是两条独立链路:绑定把设备纳入某个家庭,需要业务后台签发的设备绑定签名;分享把已绑定设备的使用权授予另一个账号,只需要设备拥有者生成的分享 Token,不改变设备的家庭归属。
前提条件
在使用设备分享能力前,请确保已完成以下准备工作:
已开通腾讯云物联网相关服务,并在控制台完成实例、应用和设备的准备工作。可参见 开通服务。
已在客户端工程中集成 IoT 应用端 SDK 并完成登录。可参见 Android SDK 集成与登录、iOS SDK 集成与登录。
分享方:目标设备已绑定到当前登录账户名下,且当前用户是设备拥有者。可参见 设备绑定。
接收方:已获得设备拥有者提供的分享 Token,以及设备的
productId 与 deviceName。获取设备管理对象
分享相关接口均由
TXIoTDeviceManager 提供。登录成功后,通过 TXIoTEngine 单例获取该对象,可长期持有。TXIoTEngine iotEngine = TXIoTEngine.getInstance(context);TXIoTDeviceManager deviceManager = iotEngine.getDeviceManager();if (deviceManager == null) {// SDK 未登录或登录已过期,请先完成登录。return;}
TXIoTDeviceManager *deviceManager = [[TXIoTEngine getInstance] getDeviceManager];if (deviceManager == nil) {// SDK 未登录或登录已过期,请先完成登录。return;}
说明:
getDeviceManager 返回 null(iOS 为 nil)表示 SDK 尚未登录或登录已过期。请在登录成功回调之后再获取该对象,不要在 App 启动阶段提前缓存。分享模型
设备分享用于把单台已绑定设备的使用权授予其他账号,典型场景是把门口摄像头分享给家政人员,或把设备临时授权给亲友查看。
分享不改变设备的家庭归属,被分享用户不会成为设备所属家庭的成员。
被分享设备不出现在被分享用户的
getDeviceList 结果中,需通过 getDeviceListSharedWithMe 单独查询。分享关系可由设备拥有者单方面撤销,也可由被分享用户自行取消。
注意:
设备分享 Token 与家庭邀请 Token 是两种不同的凭据,不可混用:家庭邀请 Token 用于加入家庭并获得该家庭下所有设备的权限,设备分享 Token 只对指定的一台设备生效。两者均属敏感凭据,请通过可信渠道传递,并避免在日志中明文输出。
完整分享流程如下:
1. 设备拥有者调用
createDeviceSharingToken,传入 familyId 与目标 deviceId,得到分享 Token。2. 拥有者通过业务自有渠道(如二维码、站内消息)把 Token 与设备的
productId、deviceName 一并发送给被分享用户。3. 被分享用户登录 SDK 后调用
bindDeviceSharedWithMe,传入 deviceId 与 Token 完成接收。4. 被分享用户通过
getDeviceListSharedWithMe 查询自己收到的共享设备。创建分享 Token 与接受分享
方法 | 说明 |
设备拥有者生成分享 Token,需传入 familyId 与 deviceId。由拥有者调用,被分享用户无此权限。 | |
被分享用户使用 Token 接收共享设备,需同时传入设备的 deviceId 与 Token,两者不匹配将绑定失败。 |
// 设备拥有者:创建分享 Token。deviceManager.createDeviceSharingToken(familyId, deviceId, new TXIoTCallback<String>() {@Overridepublic void onSuccess(String shareToken) {// 将 shareToken 与 deviceId 一并通过业务自有渠道发送给被分享用户。}@Overridepublic void onError(TXIoTErrorCode errorCode, String errorMessage) {// 创建分享 Token 失败,请根据错误码和错误信息处理。}});// 被分享用户:使用 Token 接收共享设备。deviceManager.bindDeviceSharedWithMe(deviceId, shareToken, new TXIoTCallback<Void>() {@Overridepublic void onSuccess(Void result) {// 接收成功,可调用 getDeviceListSharedWithMe 刷新共享设备列表。}@Overridepublic void onError(TXIoTErrorCode errorCode, String errorMessage) {// 接收失败,请检查 Token 是否过期,以及 deviceId 与 Token 是否匹配。}});
// 设备拥有者:创建分享 Token。TXIoTCallback<NSString *> *shareCallback = [[TXIoTCallback alloc] init];shareCallback.onSuccess = ^(NSString *shareToken) {// 将 shareToken 与 deviceId 一并通过业务自有渠道发送给被分享用户。};shareCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) {// 创建分享 Token 失败,请根据错误码和错误信息处理。};[deviceManager createDeviceSharingToken:familyId deviceId:deviceId callback:shareCallback];// 被分享用户:使用 Token 接收共享设备。TXIoTVoidCallback *bindSharedCallback = [[TXIoTVoidCallback alloc] init];bindSharedCallback.onSuccess = ^{// 接收成功,可调用 getDeviceListSharedWithMe 刷新共享设备列表。};bindSharedCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) {// 接收失败,请检查 Token 是否过期,以及 deviceId 与 Token 是否匹配。};[deviceManager bindDeviceSharedWithMe:deviceIdshareToken:shareTokencallback:bindSharedCallback];
拥有者管理共享用户
设备拥有者可查询某台设备已分享给哪些用户,并撤销指定用户的权限。
方法 | 说明 |
撤销指定用户对该设备的访问权限, userId 取自 getDeviceSharedUsers 的返回结果。 |
// 先查询共享用户列表,再基于返回的 userId 执行撤销。deviceManager.getDeviceSharedUsers(deviceId, new TXIoTCallback<List<TXIoTUserInfo>>() {@Overridepublic void onSuccess(List<TXIoTUserInfo> userList) {for (TXIoTUserInfo user : userList) {// user.userId / user.nickName / user.avatarUrl / user.deviceBindTime}if (!userList.isEmpty()) {String userId = userList.get(0).userId;deviceManager.removeDeviceSharedUser(deviceId, userId, new TXIoTCallback<Void>() {@Overridepublic void onSuccess(Void result) {// 撤销成功。}@Overridepublic void onError(TXIoTErrorCode errorCode, String errorMessage) {// 撤销失败,请根据错误码和错误信息处理。}});}}@Overridepublic void onError(TXIoTErrorCode errorCode, String errorMessage) {// 查询共享用户失败,请根据错误码和错误信息处理。}});
// 先查询共享用户列表,再基于返回的 userId 执行撤销。TXIoTCallback<NSArray<TXIoTUserInfo *> *> *usersCallback = [[TXIoTCallback alloc] init];usersCallback.onSuccess = ^(NSArray<TXIoTUserInfo *> *userList) {if (userList.count == 0) {return;}NSString *userId = userList.firstObject.userId;TXIoTVoidCallback *removeCallback = [[TXIoTVoidCallback alloc] init];removeCallback.onSuccess = ^{// 撤销成功。};removeCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) {// 撤销失败,请根据错误码和错误信息处理。};[deviceManager removeDeviceSharedUser:deviceIduserId:userIdcallback:removeCallback];};usersCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) {// 查询共享用户失败,请根据错误码和错误信息处理。};[deviceManager getDeviceSharedUsers:deviceId callback:usersCallback];
被分享用户管理共享设备
被分享用户可分页查询所有分享给自己的设备,也可主动取消接收。
方法 | 说明 |
分页查询所有分享给当前用户的设备,不需要传 familyId。分页规则与 getDeviceList 一致:首次传空字符串,nextPageToken 为空字符串表示已是最后一页。 | |
取消接收分享的设备,只需传入 deviceId。取消后不再拥有该设备的访问权限,但不影响设备与其拥有者的绑定关系。 |
// 查询分享给我的设备(首次传空字符串)。deviceManager.getDeviceListSharedWithMe("", new TXIoTCallback<TXIoTPageResult<TXIoTDeviceInfo>>() {@Overridepublic void onSuccess(TXIoTPageResult<TXIoTDeviceInfo> pageResult) {List<TXIoTDeviceInfo> sharedDevices = pageResult.dataList;String nextPageToken = pageResult.nextPageToken;// nextPageToken 非空时原样回传以获取下一页。}@Overridepublic void onError(TXIoTErrorCode errorCode, String errorMessage) {// 查询共享设备列表失败,请根据错误码和错误信息处理。}});// 取消接收共享设备。deviceManager.unbindDeviceSharedWithMe(deviceId, new TXIoTCallback<Void>() {@Overridepublic void onSuccess(Void result) {// 取消成功。}@Overridepublic void onError(TXIoTErrorCode errorCode, String errorMessage) {// 取消失败,请根据错误码和错误信息处理。}});
// 查询分享给我的设备(首次传空字符串)。TXIoTCallback<TXIoTPageResult<TXIoTDeviceInfo *> *> *sharedListCallback = [[TXIoTCallback alloc] init];sharedListCallback.onSuccess = ^(TXIoTPageResult<TXIoTDeviceInfo *> *pageResult) {NSArray<TXIoTDeviceInfo *> *sharedDevices = pageResult.dataList;NSString *nextPageToken = pageResult.nextPageToken;// nextPageToken 非空时原样回传以获取下一页。};sharedListCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) {// 查询共享设备列表失败,请根据错误码和错误信息处理。};[deviceManager getDeviceListSharedWithMe:@"" callback:sharedListCallback];// 取消接收共享设备。TXIoTVoidCallback *unbindSharedCallback = [[TXIoTVoidCallback alloc] init];unbindSharedCallback.onSuccess = ^{// 取消成功。};unbindSharedCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) {// 取消失败,请根据错误码和错误信息处理。};[deviceManager unbindDeviceSharedWithMe:deviceId callback:unbindSharedCallback];
错误处理
错误码 | 说明 | 建议处理方式 |
ERR_INVALID_PARAMETER | 参数不合法。 | 检查 productId、deviceName、familyId、分享 Token、userId 是否为空。 |
ERR_INVALID_ACCESS_TOKEN | 登录凭证无效。 | 重新登录 SDK,并重新获取设备管理对象。 |
ERR_UNAUTHORIZED_OPERATION | 当前用户无权限。 | 创建分享 Token 与撤销共享用户仅设备拥有者可执行,被分享用户调用会返回该错误。 |
ERR_DEVICE_NOT_EXIST | 设备不存在。 | 检查 productId 与 deviceName 是否正确,以及设备是否仍处于绑定状态。 |
ERR_DEVICE_OFFLINE | 设备离线。 | 分享关系本身不受在线状态影响;若后续拉流或控制失败,引导用户检查设备网络。 |
ERR_RATE_LIMITED | 请求被限频。 | 降低调用频率,避免高频轮询共享用户列表或共享设备列表。 |
错误码 | 说明 | 建议处理方式 |
TXIoTErrorCodeInvalidParameter | 参数不合法。 | 检查 productId、deviceName、familyId、分享 Token、userId 是否为空。 |
TXIoTErrorCodeInvalidAccessToken | 登录凭证无效。 | 重新登录 SDK,并重新获取设备管理对象。 |
TXIoTErrorCodeUnauthorizedOperation | 当前用户无权限。 | 创建分享 Token 与撤销共享用户仅设备拥有者可执行,被分享用户调用会返回该错误。 |
TXIoTErrorCodeDeviceNotExist | 设备不存在。 | 检查 productId 与 deviceName 是否正确,以及设备是否仍处于绑定状态。 |
TXIoTErrorCodeDeviceOffline | 设备离线。 | 分享关系本身不受在线状态影响;若后续拉流或控制失败,引导用户检查设备网络。 |
TXIoTErrorCodeRateLimited | 请求被限频。 | 降低调用频率,避免高频轮询共享用户列表或共享设备列表。 |
常见问题
设备分享和把成员加入家庭有什么区别?
两者的授权粒度不同:
加入家庭:被邀请用户成为家庭成员,可访问该家庭下的全部设备,后续新绑定的设备也自动可见。适用于家人共用。
设备分享:被分享用户只获得指定单台设备的使用权,不进入家庭,也看不到家庭内的其他设备。适用于临时授权给外部人员。
被分享的设备不出现在
getDeviceList 的结果中,必须通过 getDeviceListSharedWithMe 查询。解绑设备后,之前分享出去的用户还能访问吗?
不能。设备解绑意味着它从该家庭中被移除,依附于这台设备的分享关系随之失效。若需要将设备迁移到另一个家庭,请先解绑,再用新的设备绑定签名绑定到目标家庭,绑定完成后需重新创建分享 Token 并让对方重新接收。
被分享用户能对设备做哪些操作?
被分享用户获得的是该台设备的使用权,可以拉流监控、发起通话、下发控制命令;但不具备管理权:无法解绑设备、无法修改设备别名与房间归属、无法再把该设备转分享给第三方,也看不到设备所属家庭内的其他设备。
同一台设备可以分享给多少个用户?
getDeviceSharedUsers 单次最多返回 100 条共享用户记录且不支持分页,因此建议在产品侧把单台设备的共享用户数控制在 100 以内,避免列表展示不全。接口参考
本文涉及接口的完整定义参见: