注意:说明:
注意:家庭、房间、成员三者的关系:家庭是权限边界,成员加入家庭后可访问该家庭下的全部设备;房间仅用于在 App 内对设备做分组展示,是可选概念,不影响权限;成员通过邀请 Token 加入,分为管理员与普通成员两种角色。
一、前提条件
在使用这篇能力前,请确保已完成以下准备工作:
·已开通腾讯云物联网相关服务,并在控制台完成实例与应用的准备工作。可参见 开通服务。
·已在客户端工程中集成 IoT 应用端 SDK 并完成登录。可参见 Android SDK 集成与登录、iOS SDK 集成与登录、小程序 SDK 集成与登录、鸿蒙 SDK 集成与登录。
二、获取家庭管理对象
登录成功后,通过 TXIoTEngine 单例获取 TXIoTFamilyManager。该对象是这篇所有操作的入口,可长期持有。
AndroidiOS小程序鸿蒙TXIoTEngine iotEngine = TXIoTEngine.getInstance(context);TXIoTFamilyManager familyManager = iotEngine.getFamilyManager();if (familyManager == null) { // SDK 未登录或登录已过期,请先完成登录。 return;}TXIoTFamilyManager *familyManager = [[TXIoTEngine getInstance] getFamilyManager];if (familyManager == nil) { // SDK 未登录或登录已过期,请先完成登录。 return;}const { TXIoTEngine } = requirePlugin('tx-iot-sdk');// getInstance 为异步方法,首次调用会等待内部模块加载完成。const iotEngine = await TXIoTEngine.getInstance();const familyManager = iotEngine.getFamilyManager();if (familyManager == null) { // SDK 未登录或登录已过期,请先完成登录。 return;}import { getIoTEngineInstance, TXIoTEngine } from '@tencentcloud/liteavsdk_iot'const iotEngine: TXIoTEngine = getIoTEngineInstance()const familyManager = iotEngine.getFamilyManager()if (familyManager == null) { // SDK 未登录或登录已过期,请先完成登录。 return}
注意:说明:
注意:getFamilyManager 返回空值(Android、小程序与鸿蒙为 null,iOS 为 nil)表示 SDK 尚未登录或登录已过期。请在登录成功回调之后再获取该对象,不要在 App 启动阶段提前缓存。
四、查询与创建家庭
App 启动后的标准流程是:先调用 getFamilyList 查询家庭列表;若列表为空(新注册账号),再调用 createFamily 创建一个默认家庭。
返回的 TXIoTFamilyInfo 中的 role 表示当前用户在该家庭中的角色,取值仅为管理员或普通成员两种,可据此决定是否展示邀请成员、删除家庭等管理入口。
| 方法 | 说明 |
| getFamilyList | 查询当前用户所属的全部家庭,返回 TXIoTFamilyInfo 列表。包含自己创建的家庭和被邀请加入的家庭。 |
| createFamily | 创建家庭,name 不可为空,返回含 familyId 的家庭信息。 |
AndroidiOS小程序鸿蒙familyManager.getFamilyList(new TXIoTCallback<List<TXIoTFamilyInfo>>() { @Override public void onSuccess(List<TXIoTFamilyInfo> familyList) { if (familyList.isEmpty()) { // 新账号尚无家庭,创建一个默认家庭。 familyManager.createFamily("我的家", new TXIoTCallback<TXIoTFamilyInfo>() { @Override public void onSuccess(TXIoTFamilyInfo familyInfo) { String familyId = familyInfo.familyId; } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 创建家庭失败,请检查家庭名称是否为空。 } }); return; } TXIoTFamilyInfo family = familyList.get(0); String familyId = family.familyId; boolean isAdmin = family.role == TXIoTFamilyRole.ADMIN; } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 查询家庭列表失败,请根据错误码和错误信息处理。 }});TXIoTCallback<NSArray<TXIoTFamilyInfo *> *> *listCallback = [[TXIoTCallback alloc] init];listCallback.onSuccess = ^(NSArray<TXIoTFamilyInfo *> *familyList) { if (familyList.count == 0) { // 新账号尚无家庭,创建一个默认家庭。 TXIoTCallback<TXIoTFamilyInfo *> *createCallback = [[TXIoTCallback alloc] init]; createCallback.onSuccess = ^(TXIoTFamilyInfo *familyInfo) { NSString *familyId = familyInfo.familyId; }; createCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 创建家庭失败,请检查家庭名称是否为空。 }; [familyManager createFamily:@"我的家" callback:createCallback]; return; } TXIoTFamilyInfo *family = familyList.firstObject; NSString *familyId = family.familyId; BOOL isAdmin = (family.role == TXIoTFamilyRoleAdmin);};listCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 查询家庭列表失败,请根据错误码和错误信息处理。};[familyManager getFamilyList:listCallback];try { let familyList = await familyManager.getFamilyList(); if (familyList.length === 0) { // 新账号尚无家庭,创建一个默认家庭。 const familyInfo = await familyManager.createFamily('我的家'); familyList = [familyInfo]; } const family = familyList[0]; const familyId = family.familyId; // role:1 为普通成员、2 为管理员,可据此控制管理入口的展示。 const isAdmin = family.role === 2;} catch (err) { // 查询或创建失败,请根据 err.code 和 err.message 处理。}import { TXIoTFamilyRole } from '@tencentcloud/liteavsdk_iot'familyManager.getFamilyList({ onSuccess: (familyList) => { if (familyList.length === 0) { // 新账号尚无家庭,创建一个默认家庭。 familyManager.createFamily('我的家', { onSuccess: (familyInfo) => { const familyId = familyInfo.familyId }, onError: (errorCode, errorMessage) => { // 创建家庭失败,请检查家庭名称是否为空。 } }) return } const family = familyList[0] const familyId = family.familyId const isAdmin = family.role === TXIoTFamilyRole.ADMIN }, onError: (errorCode, errorMessage) => { // 查询家庭列表失败,请根据错误码和错误信息处理。 }})
六、成员角色
家庭成员分为两种角色,通过 TXIoTUserInfo.role 与 TXIoTFamilyInfo.role 获取:
| 角色 | 说明 |
| 管理员 | 家庭的创建者。可邀请成员、移除成员、删除家庭,并拥有家庭下全部设备的完整权限。 |
| 普通成员 | 通过邀请 Token 加入的用户。可访问和控制家庭下的全部设备,但不具备成员管理与家庭删除权限。 |
七、邀请成员加入家庭
管理员创建邀请 Token,通过业务自有渠道发送给目标用户;目标用户登录 SDK 后使用该 Token 加入家庭。
注意:邀请 Token 与设备分享 Token 是两种不同凭据:邀请 Token 让对方成为家庭成员并获得家庭下全部设备的权限;设备分享 Token 只授予单台设备的使用权。若只想临时授权一台设备,请改用设备分享,参见 设备分享。两者均属敏感凭据,请通过可信渠道传递,避免在日志中明文输出。
| 方法 | 说明 |
| createFamilyInviteToken | 管理员为指定家庭创建邀请 Token。普通成员调用会返回无权限错误。 |
| joinFamilyAsMember | 被邀请用户使用邀请 Token 加入家庭,只需传 Token,无需 familyId。加入成功后再次 getFamilyList 即可看到该家庭。 |
AndroidiOS小程序鸿蒙// 管理员:创建邀请 Token。familyManager.createFamilyInviteToken(familyId, new TXIoTCallback<String>() { @Override public void onSuccess(String inviteToken) { // 通过业务自有渠道把 inviteToken 发送给被邀请用户。 } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 创建邀请 Token 失败,请确认当前用户是该家庭的管理员。 }});// 被邀请用户:使用邀请 Token 加入家庭。familyManager.joinFamilyAsMember(inviteToken, new TXIoTCallback<Void>() { @Override public void onSuccess(Void result) { // 加入成功,重新调用 getFamilyList 即可看到该家庭。 } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 加入失败,请检查邀请 Token 是否为空或已过期。 }});// 管理员:创建邀请 Token。TXIoTCallback<NSString *> *tokenCallback = [[TXIoTCallback alloc] init];tokenCallback.onSuccess = ^(NSString *inviteToken) { // 通过业务自有渠道把 inviteToken 发送给被邀请用户。};tokenCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 创建邀请 Token 失败,请确认当前用户是该家庭的管理员。};[familyManager createFamilyInviteToken:familyId callback:tokenCallback];// 被邀请用户:使用邀请 Token 加入家庭。TXIoTVoidCallback *joinCallback = [[TXIoTVoidCallback alloc] init];joinCallback.onSuccess = ^{ // 加入成功,重新调用 getFamilyList 即可看到该家庭。};joinCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 加入失败,请检查邀请 Token 是否为空或已过期。};[familyManager joinFamilyAsMember:inviteToken callback:joinCallback];// 管理员:创建邀请 Token。try { const inviteToken = await familyManager.createFamilyInviteToken(familyId); // 通过业务自有渠道把 inviteToken 发送给被邀请用户。} catch (err) { // 创建邀请 Token 失败,请确认当前用户是该家庭的管理员。}// 被邀请用户:使用邀请 Token 加入家庭。try { await familyManager.joinFamilyAsMember(inviteToken); // 加入成功,重新调用 getFamilyList 即可看到该家庭。} catch (err) { // 加入失败,请检查邀请 Token 是否为空或已过期。}// 管理员:创建邀请 Token。familyManager.createFamilyInviteToken(familyId, { onSuccess: (inviteToken) => { // 通过业务自有渠道把 inviteToken 发送给被邀请用户。 }, onError: (errorCode, errorMessage) => { // 创建邀请 Token 失败,请确认当前用户是该家庭的管理员。 }})// 被邀请用户:使用邀请 Token 加入家庭。familyManager.joinFamilyAsMember(inviteToken, { onSuccess: () => { // 加入成功,重新调用 getFamilyList 即可看到该家庭。 }, onError: (errorCode, errorMessage) => { // 加入失败,请检查邀请 Token 是否为空或已过期。 }})
八、查询成员、移除成员与退出家庭
removeMemberFromFamily 一个接口承载两种语义,由传入的 userId 决定:
·传入其他成员的 userId → 管理员将该成员移出家庭。
·传入当前登录用户自己的 userId → 当前用户主动退出该家庭。
| 方法 | 说明 |
| getMemberList | 查询家庭成员列表,返回 TXIoTUserInfo 列表,含 userId、nickName、avatarUrl、role。该接口不分页。 |
| removeMemberFromFamily | 移除成员或退出家庭,语义由 userId 是否为当前登录用户决定。userId 取自 getMemberList 的返回结果。 |
AndroidiOS小程序鸿蒙// 先查询成员列表,再基于返回的 userId 执行移除或退出。familyManager.getMemberList(familyId, new TXIoTCallback<List<TXIoTUserInfo>>() { @Override public void onSuccess(List<TXIoTUserInfo> memberList) { if (memberList == null || memberList.isEmpty()) { // 家庭下没有成员,无需继续操作。 return; } for (TXIoTUserInfo member : memberList) { // member.userId / member.nickName / member.avatarUrl / member.role } TXIoTUserInfo self = iotEngine.getLoginUserInfo(); String targetUserId = memberList.get(0).userId; boolean isSelf = self != null && targetUserId.equals(self.userId); // isSelf 为 true 时语义是「退出家庭」,否则是「管理员移除成员」。 familyManager.removeMemberFromFamily(familyId, targetUserId, new TXIoTCallback<Void>() { @Override public void onSuccess(Void result) { // 操作成功,请刷新成员列表或家庭列表。 } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 操作失败,请确认权限,并确认 userId 取自 getMemberList。 } }); } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 查询成员列表失败,请根据错误码和错误信息处理。 }});// 先查询成员列表,再基于返回的 userId 执行移除或退出。TXIoTCallback<NSArray<TXIoTUserInfo *> *> *memberCallback = [[TXIoTCallback alloc] init];memberCallback.onSuccess = ^(NSArray<TXIoTUserInfo *> *memberList) { if (memberList.count == 0) { return; } TXIoTUserInfo *self = [[TXIoTEngine getInstance] getLoginUserInfo]; NSString *targetUserId = memberList.firstObject.userId; BOOL isSelf = [targetUserId isEqualToString:self.userId]; // isSelf 为 YES 时语义是「退出家庭」,否则是「管理员移除成员」。 TXIoTVoidCallback *removeCallback = [[TXIoTVoidCallback alloc] init]; removeCallback.onSuccess = ^{ // 操作成功,请刷新成员列表或家庭列表。 }; removeCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 操作失败,请确认权限,并确认 userId 取自 getMemberList。 }; [familyManager removeMemberFromFamily:familyId userId:targetUserId callback:removeCallback];};memberCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 查询成员列表失败,请根据错误码和错误信息处理。};[familyManager getMemberList:familyId callback:memberCallback];// 先查询成员列表,再基于返回的 userId 执行移除或退出。try { const memberList = await familyManager.getMemberList(familyId); for (const member of memberList) { // member.userId / member.nickName / member.avatarUrl / member.role } if (memberList.length > 0) { const self = iotEngine.getLoginUserInfo(); const targetUserId = memberList[0].userId; const isSelf = self != null && targetUserId === self.userId; // isSelf 为 true 时语义是「退出家庭」,否则是「管理员移除成员」。 await familyManager.removeMemberFromFamily(familyId, targetUserId); // 操作成功,请刷新成员列表或家庭列表。 }} catch (err) { // 查询或操作失败,请确认权限,并确认 userId 取自 getMemberList。}// 先查询成员列表,再基于返回的 userId 执行移除或退出。familyManager.getMemberList(familyId, { onSuccess: (memberList) => { if (memberList.length === 0) { // 家庭下没有成员,无需继续操作。 return } for (const member of memberList) { // member.userId / member.nickName / member.avatarUrl / member.role } const self = iotEngine.getLoginUserInfo() const targetUserId = memberList[0].userId const isSelf = self != null && targetUserId === self.userId // isSelf 为 true 时语义是「退出家庭」,否则是「管理员移除成员」。 familyManager.removeMemberFromFamily(familyId, targetUserId, { onSuccess: () => { // 操作成功,请刷新成员列表或家庭列表。 }, onError: (errorCode, errorMessage) => { // 操作失败,请确认权限,并确认 userId 取自 getMemberList。 } }) }, onError: (errorCode, errorMessage) => { // 查询成员列表失败,请根据错误码和错误信息处理。 }})
九、修改家庭名称与删除家庭
注意:updateFamilyInfo 目前仅支持修改家庭名称:传入的 TXIoTFamilyInfo 中 familyId 用于定位家庭、name 为新名称且不可为空,其余字段(role、createTime、updateTime)为只读,填写后不会生效。
| 方法 | 说明 |
| updateFamilyInfo | 修改家庭名称。name 为空时返回参数不合法错误,且不会发起网络请求。 |
| deleteFamily | 删除家庭。删除后该家庭下的房间、成员关系一并失效,请在调用前二次确认。仅管理员可执行。 |
注意:警告:
注意:deleteFamily 为高危操作,删除后不可恢复:
注意:调用前请务必在 App 内弹窗二次确认,向用户明确说明删除后果;如需保留设备,请先引导用户将设备解绑并重新绑定到其他家庭(参见常见问题 删除家庭后,家庭下的设备会怎样)。
AndroidiOS小程序鸿蒙// 修改家庭名称:familyId 定位家庭,name 为新名称。TXIoTFamilyInfo newInfo = new TXIoTFamilyInfo();newInfo.familyId = familyId;newInfo.name = "度假别墅";familyManager.updateFamilyInfo(newInfo, new TXIoTCallback<Void>() { @Override public void onSuccess(Void result) { // 修改成功,可直接更新本地 UI。 } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 修改失败,请检查家庭名称是否为空。 }});// 删除家庭(建议先弹窗二次确认)。familyManager.deleteFamily(familyId, new TXIoTCallback<Void>() { @Override public void onSuccess(Void result) { // 删除成功,请刷新家庭列表并切换到其他家庭。 } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 删除失败,请确认当前用户是该家庭的管理员。 }});// 修改家庭名称:familyId 定位家庭,name 为新名称。TXIoTFamilyInfo *newInfo = [[TXIoTFamilyInfo alloc] init];newInfo.familyId = familyId;newInfo.name = @"度假别墅";TXIoTVoidCallback *updateCallback = [[TXIoTVoidCallback alloc] init];updateCallback.onSuccess = ^{ // 修改成功,可直接更新本地 UI。};updateCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 修改失败,请检查家庭名称是否为空。};[familyManager updateFamilyInfo:newInfo callback:updateCallback];// 删除家庭(建议先弹窗二次确认)。TXIoTVoidCallback *deleteCallback = [[TXIoTVoidCallback alloc] init];deleteCallback.onSuccess = ^{ // 删除成功,请刷新家庭列表并切换到其他家庭。};deleteCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 删除失败,请确认当前用户是该家庭的管理员。};[familyManager deleteFamily:familyId callback:deleteCallback];// 修改家庭名称:familyId 定位家庭,name 为新名称。try { await familyManager.updateFamilyInfo({ familyId, name: '度假别墅' }); // 修改成功,可直接更新本地 UI。} catch (err) { // 修改失败,请检查家庭名称是否为空。}// 删除家庭(建议先弹窗二次确认)。try { await familyManager.deleteFamily(familyId); // 删除成功,请刷新家庭列表并切换到其他家庭。} catch (err) { // 删除失败,请确认当前用户是该家庭的管理员。}import { TXIoTFamilyInfo } from '@tencentcloud/liteavsdk_iot'// 修改家庭名称:familyId 定位家庭,name 为新名称。const newInfo = new TXIoTFamilyInfo()newInfo.familyId = familyIdnewInfo.name = '度假别墅'familyManager.updateFamilyInfo(newInfo, { onSuccess: () => { // 修改成功,可直接更新本地 UI。 }, onError: (errorCode, errorMessage) => { // 修改失败,请检查家庭名称是否为空。 }})// 删除家庭(建议先弹窗二次确认)。familyManager.deleteFamily(familyId, { onSuccess: () => { // 删除成功,请刷新家庭列表并切换到其他家庭。 }, onError: (errorCode, errorMessage) => { // 删除失败,请确认当前用户是该家庭的管理员。 }})
十、管理房间
房间用于在 App 内对家庭下的设备做分组展示。房间是可选概念:设备刚绑定时不属于任何房间,是否加入房间不影响设备的绑定状态、访问权限与功能使用。若业务不需要分组,可跳过本章。
注意:说明:
注意:房间只负责“分组”,不构成权限边界:设备的访问权限由家庭成员关系与设备分享决定,与房间归属无关。房间本身的增删改查由 TXIoTFamilyManager 提供,把设备加入或移出房间由 TXIoTDeviceManager 提供,两者均在本章介绍。
十一、创建、查询与维护房间
| 方法 | 说明 |
| createRoom | 在指定家庭下创建房间,name 不可为空,返回含 roomId 的 TXIoTRoomInfo。 |
| getRoomList | 查询家庭下的房间列表。返回的 TXIoTRoomInfo.deviceCount 为该房间内的设备数量。该接口不分页。 |
| setRoomName | 重命名房间,roomId 与 name 均不可为空。 |
| deleteRoom | 删除房间。房间内的设备不会被解绑,只是恢复为“未分配房间”状态。 |
AndroidiOS小程序鸿蒙// 创建房间。familyManager.createRoom(familyId, "客厅", new TXIoTCallback<TXIoTRoomInfo>() { @Override public void onSuccess(TXIoTRoomInfo roomInfo) { String roomId = roomInfo.roomId; // 后续可按「设备的房间归属」小节把设备加入该房间。 } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 创建房间失败,请检查房间名称是否为空。 }});// 查询房间列表。familyManager.getRoomList(familyId, new TXIoTCallback<List<TXIoTRoomInfo>>() { @Override public void onSuccess(List<TXIoTRoomInfo> roomList) { for (TXIoTRoomInfo room : roomList) { // room.roomId / room.name / room.deviceCount } } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 查询房间列表失败,请根据错误码和错误信息处理。 }});// 重命名房间。familyManager.setRoomName(familyId, roomId, "主卧", new TXIoTCallback<Void>() { @Override public void onSuccess(Void result) { // 重命名成功。 } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 重命名失败,请根据错误码和错误信息处理。 }});// 删除房间(房间内设备不会被解绑)。familyManager.deleteRoom(familyId, roomId, new TXIoTCallback<Void>() { @Override public void onSuccess(Void result) { // 删除成功,请刷新房间列表。 } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 删除失败,请根据错误码和错误信息处理。 }});// 创建房间。TXIoTCallback<TXIoTRoomInfo *> *createCallback = [[TXIoTCallback alloc] init];createCallback.onSuccess = ^(TXIoTRoomInfo *roomInfo) { NSString *roomId = roomInfo.roomId; // 后续可按「设备的房间归属」小节把设备加入该房间。};createCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 创建房间失败,请检查房间名称是否为空。};[familyManager createRoom:familyId name:@"客厅" callback:createCallback];// 查询房间列表。TXIoTCallback<NSArray<TXIoTRoomInfo *> *> *roomListCallback = [[TXIoTCallback alloc] init];roomListCallback.onSuccess = ^(NSArray<TXIoTRoomInfo *> *roomList) { for (TXIoTRoomInfo *room in roomList) { // room.roomId / room.name / room.deviceCount }};roomListCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 查询房间列表失败,请根据错误码和错误信息处理。};[familyManager getRoomList:familyId callback:roomListCallback];// 重命名房间。TXIoTVoidCallback *renameCallback = [[TXIoTVoidCallback alloc] init];renameCallback.onSuccess = ^{ // 重命名成功。};renameCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 重命名失败,请根据错误码和错误信息处理。};[familyManager setRoomName:familyId roomId:roomId name:@"主卧" callback:renameCallback];// 删除房间(房间内设备不会被解绑)。TXIoTVoidCallback *deleteRoomCallback = [[TXIoTVoidCallback alloc] init];deleteRoomCallback.onSuccess = ^{ // 删除成功,请刷新房间列表。};deleteRoomCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 删除失败,请根据错误码和错误信息处理。};[familyManager deleteRoom:familyId roomId:roomId callback:deleteRoomCallback];try { // 创建房间。 const roomInfo = await familyManager.createRoom(familyId, '客厅'); const roomId = roomInfo.roomId; // 后续可按「设备的房间归属」小节把设备加入该房间。 // 查询房间列表。 const roomList = await familyManager.getRoomList(familyId); for (const room of roomList) { // room.roomId / room.name / room.deviceCount } // 重命名房间。 await familyManager.setRoomName(familyId, roomId, '主卧'); // 删除房间(房间内设备不会被解绑)。 await familyManager.deleteRoom(familyId, roomId); // 删除成功,请刷新房间列表。} catch (err) { // 操作失败,请根据 err.code 和 err.message 处理。}// 创建房间。familyManager.createRoom(familyId, '客厅', { onSuccess: (roomInfo) => { const roomId = roomInfo.roomId // 后续可按「设备的房间归属」小节把设备加入该房间。 }, onError: (errorCode, errorMessage) => { // 创建房间失败,请检查房间名称是否为空。 }})// 查询房间列表。familyManager.getRoomList(familyId, { onSuccess: (roomList) => { for (const room of roomList) { // room.roomId / room.name / room.deviceCount } }, onError: (errorCode, errorMessage) => { // 查询房间列表失败,请根据错误码和错误信息处理。 }})// 重命名房间。familyManager.setRoomName(familyId, roomId, '主卧', { onSuccess: () => { // 重命名成功。 }, onError: (errorCode, errorMessage) => { // 重命名失败,请根据错误码和错误信息处理。 }})// 删除房间(房间内设备不会被解绑)。familyManager.deleteRoom(familyId, roomId, { onSuccess: () => { // 删除成功,请刷新房间列表。 }, onError: (errorCode, errorMessage) => { // 删除失败,请根据错误码和错误信息处理。 }})
十二、设备的房间归属
创建房间后,即可把设备归入房间。设备刚绑定时不属于任何房间,加入房间不影响设备的绑定状态与功能使用。
以下两个接口属于设备管理,需先通过 TXIoTEngine 的 getDeviceManager 获取 TXIoTDeviceManager 对象;设备的绑定与解绑参见 设备绑定。
| 方法 | 说明 |
| addDeviceToRoom | 将设备加入指定房间,需传入 deviceId、familyId 与 roomId。重复调用会覆盖设备原有的房间归属。 |
| removeDeviceFromRoom | 将设备从当前房间移出,只需传入 deviceId 与 familyId,无需 roomId。移出后设备仍绑定在该家庭下。 |
AndroidiOS小程序鸿蒙// 将设备加入房间。deviceManager.addDeviceToRoom(deviceId, familyId, roomId, new TXIoTCallback<Void>() { @Override public void onSuccess(Void result) { // 加入房间成功。 } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 加入房间失败,请根据错误码和错误信息处理。 }});// 将设备移出房间(无需传 roomId)。deviceManager.removeDeviceFromRoom(deviceId, familyId, new TXIoTCallback<Void>() { @Override public void onSuccess(Void result) { // 移出房间成功。 } @Override public void onError(TXIoTErrorCode errorCode, String errorMessage) { // 移出房间失败,请根据错误码和错误信息处理。 }});// 将设备加入房间。TXIoTVoidCallback *addCallback = [[TXIoTVoidCallback alloc] init];addCallback.onSuccess = ^{ // 加入房间成功。};addCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 加入房间失败,请根据错误码和错误信息处理。};[deviceManager addDeviceToRoom:deviceId familyId:familyId roomId:roomId callback:addCallback];// 将设备移出房间(无需传 roomId)。TXIoTVoidCallback *removeCallback = [[TXIoTVoidCallback alloc] init];removeCallback.onSuccess = ^{ // 移出房间成功。};removeCallback.onError = ^(TXIoTErrorCode errorCode, NSString *errorMessage) { // 移出房间失败,请根据错误码和错误信息处理。};[deviceManager removeDeviceFromRoom:deviceId familyId:familyId callback:removeCallback];try { // 将设备加入房间。 await deviceManager.addDeviceToRoom(deviceId, familyId, roomId); // 将设备移出房间(无需传 roomId)。 await deviceManager.removeDeviceFromRoom(deviceId, familyId);} catch (err) { // 操作失败,请根据 err.code 和 err.message 处理。}// 将设备加入房间。deviceManager.addDeviceToRoom(deviceId, familyId, roomId, { onSuccess: () => { // 加入房间成功。 }, onError: (errorCode, errorMessage) => { // 加入房间失败,请根据错误码和错误信息处理。 }})// 将设备移出房间(无需传 roomId)。deviceManager.removeDeviceFromRoom(deviceId, familyId, { onSuccess: () => { // 移出房间成功。 }, onError: (errorCode, errorMessage) => { // 移出房间失败,请根据错误码和错误信息处理。 }})
十三、使用建议
·调用顺序:登录 → getFamilyManager → getFamilyList(空则 createFamily)→ 保存 familyId → 按需管理房间与成员。所有接口都依赖有效登录态,登录过期后需重新登录并重新获取管理对象。
·以 familyId 为业务主键:切换家庭时需同步刷新设备列表、房间列表与成员列表,不要跨家庭复用缓存。
·按角色控制 UI:用 TXIoTFamilyInfo.role 判断是否展示邀请成员、移除成员、删除家庭等入口,避免普通成员触发无权限错误。
·房间归属需要两个管理对象:创建/重命名/删除房间用 TXIoTFamilyManager,把设备加入或移出房间用 TXIoTDeviceManager。删除房间不会解绑设备,只是把设备恢复为未分配房间状态。
十四、错误处理
家庭管理相关的常见错误码如下,完整定义参见 TXIoTErrorCode。
AndroidiOS小程序鸿蒙
| 错误码 | 说明 | 建议处理方式 |
| ERR_INVALID_PARAMETER | 参数不合法。 | 检查家庭名称、房间名称、roomId、邀请 Token、userId 是否为空。 |
| ERR_INVALID_ACCESS_TOKEN | 登录凭证无效。 | 重新登录 SDK,并重新获取管理对象。 |
| ERR_UNAUTHORIZED_OPERATION | 当前用户无权限。 | 普通成员无法邀请成员、移除他人或删除家庭,请先确认 role 为管理员。 |
| ERR_FAMILY_NOT_EXIST | 家庭不存在。 | 家庭可能已被删除或已退出,重新调用 getFamilyList 刷新。 |
| ERR_DEVICE_NOT_EXIST | 设备不存在。 | 调整设备房间归属时出现,请检查 deviceId 是否正确、设备是否仍绑定在该家庭下。 |
| ERR_RATE_LIMITED | 请求被限频。 | 降低调用频率,避免高频轮询家庭或成员列表 |
| 错误码 | 说明 | 建议处理方式 |
| TXIoTErrorCodeInvalidParameter | 参数不合法。 | 检查家庭名称、房间名称、roomId、邀请 Token、userId 是否为空。 |
| TXIoTErrorCodeInvalidAccessToken | 登录凭证无效。 | 重新登录 SDK,并重新获取管理对象。 |
| TXIoTErrorCodeUnauthorizedOperation | 当前用户无权限。 | 普通成员无法邀请成员、移除他人或删除家庭,请先确认 role 为管理员。 |
| TXIoTErrorCodeFamilyNotExist | 家庭不存在。 | 家庭可能已被删除或已退出,重新调用 getFamilyList 刷新。 |
| TXIoTErrorCodeDeviceNotExist | 设备不存在。 | 调整设备房间归属时出现,请检查 deviceId 是否正确、设备是否仍绑定在该家庭下。 |
| TXIoTErrorCodeRateLimited | 请求被限频。 | 降低调用频率,避免高频轮询家庭或成员列表。 |
| 错误码 | 说明 | 建议处理方式 |
| InvalidParameter | 参数不合法。 | 检查家庭名称、房间名称、roomId、邀请 Token、userId 是否为空。 |
| InvalidAccessToken | 登录凭证无效。 | 重新登录 SDK,并重新获取管理对象。 |
| UnauthorizedOperation | 当前用户无权限。 | 普通成员无法邀请成员、移除他人或删除家庭,请先确认 role 为管理员。 |
| FamilyNotExist | 家庭不存在。 | 家庭可能已被删除或已退出,重新调用 getFamilyList 刷新。 |
| DeviceNotExist | 设备不存在。 | 调整设备房间归属时出现,请检查 productId 与 deviceName 是否正确、设备是否仍绑定在该家庭下。 |
| RateLimited | 请求被限频。 | 降低调用频率,避免高频轮询家庭或成员列表。 |
| 错误码 | 说明 | 建议处理方式 |
| ERR_INVALID_PARAMETER | 参数不合法。 | 检查家庭名称、房间名称、roomId、邀请 Token、userId 是否为空。 |
| ERR_INVALID_ACCESS_TOKEN | 登录凭证无效。 | 重新登录 SDK,并重新获取管理对象。 |
| ERR_UNAUTHORIZED_OPERATION | 当前用户无权限。 | 普通成员无法邀请成员、移除他人或删除家庭,请先确认 role 为管理员。 |
| ERR_FAMILY_NOT_EXIST | 家庭不存在。 | 家庭可能已被删除或已退出,重新调用 getFamilyList 刷新。 |
| ERR_DEVICE_NOT_EXIST | 设备不存在。 | 调整设备房间归属时出现,请检查 productId 与 deviceName 是否正确、设备是否仍绑定在该家庭下。 |
| ERR_RATE_LIMITED | 请求被限频。 | 降低调用频率,避免高频轮询家庭或成员列表。 |
十六、一个账号可以有多个家庭吗?
可以。getFamilyList 返回当前用户所属的全部家庭,既包含自己创建的(角色为管理员),也包含被邀请加入的(角色为普通成员)。App 通常在首页提供家庭切换入口,切换后需以新的 familyId 重新拉取设备、房间与成员列表。
十七、房间是必须创建的吗?
不是。房间只用于在 App 内对设备做分组展示,设备不加入任何房间也能正常绑定、查看和控制。若业务不需要分组功能,可以完全跳过房间相关接口。
十八、邀请成员和设备分享该如何选择?
按授权范围选择:
·需要对方访问家庭下全部设备、且未来新增设备也自动可见 → 用邀请 Token 让其加入家庭。
·只需授权单台设备、且不希望对方看到其他设备 → 用设备分享,参见 设备分享。
十九、如何主动退出一个家庭?
调用 removeMemberFromFamily,userId 传入当前登录用户自己的 userId(可从 TXIoTEngine.getLoginUserInfo 获取)。SDK 会自动识别为退出家庭而非移除他人,因此普通成员也能成功执行。
20、删除家庭后,家庭下的设备会怎样?
删除家庭会一并失效该家庭下的房间与成员关系。请在删除前提示用户确认,并引导其先将需要保留的设备解绑后重新绑定到其他家庭,参见 设备绑定。
21、接口参考
这篇涉及接口的完整定义参见:
·TXIoTFamilyManager(Android)
·TXIoTFamilyManager(iOS)
·TXIoTFamilyManager(小程序)
·TXIoTFamilyManager(鸿蒙)
·TXIoTDeviceManager(Android)
·TXIoTDeviceManager(iOS)
·TXIoTDeviceManager(小程序)
·TXIoTDeviceManager(鸿蒙)
·TXIoTEngineDef(数据结构与错误码)
拿到 familyId 后,可继续接入 设备绑定,再按需接入 远程控制。