群组管理
更新时间: 2024/03/14 16:36:30
网易云信 NIM SDK 提供了高级群形式的群组功能,支持用户创建、加入、退出、转让、修改、查询、解散群组,拥有完善的管理功能。
技术原理
网易云信 NIM SDK 的 TeamService
提供群组操作相关接口, TeamServiceObserver
提供群组相关观察者通知接口,帮助您快速实现和使用群组的管理功能。
群组相关 API 都挂载在 team
模块中,使用 com.netease.nimlib.sdk.team
程序包。
群组相关事件监听
在进行群组操作前,您可以提前注册监听群相关事件。监听后,在进行群组管理相关操作时,会收到对应的通知。
可以根据用户需求,调用以下方法进行监听。
observeMemberRemove
:移除群成员的观察者通知observeMemberUpdate
:群成员信息变化观察者通知observeTeamRemove
:移除群的观察者通知observeTeamUpdate
:群信息变动观察者通知
示例代码如下:
// 移除群成员的观察者通知。
private Observer<TeamMember> memberRemoveObserver = new Observer<TeamMember>() {
@Override
public void onEvent(TeamMember member) {
}
};
// 注册/注销观察者
NIMClient.getService(TeamServiceObserver.class).observeMemberRemove(memberRemoveObserver, register);
// 群成员信息变化观察者通知。群组添加新成员,成员信息变化会收到该通知。
// 返回的参数为有更新的群成员信息列表。
Observer<List<TeamMember>> memberUpdateObserver = new Observer<List<TeamMember>>() {
@Override
public void onEvent(List<TeamMember> members) {
}
};
// 注册/注销观察者
NIMClient.getService(TeamServiceObserver.class).observeMemberUpdate(memberUpdateObserver, register);
// 创建群组被移除的观察者。在退群,被踢,群被解散时会收到该通知。
Observer<Team> teamRemoveObserver = new Observer<Team>() {
@Override
public void onEvent(Team team) {
// 由于界面上可能仍需要显示群组名等信息,因此参数中会返回 Team 对象。
// 该对象的 isMyTeam 接口返回为 false。
}
};
// 注册/注销观察者
NIMClient.getService(TeamServiceObserver.class).observeTeamRemove(teamRemoveObserver, register);
// 创建群组信息变动观察者
Observer<List<Team>> teamUpdateObserver = new Observer<List<Team>>() {
@Override
public void onEvent(List<Team> teams) {
}
};
// 注册/注销观察者
NIMClient.getService(TeamServiceObserver.class).observeTeamUpdate(teamUpdateObserver, register);
由于获取群组信息和群成员信息需要跨进程异步调用,开发者最好能在第三方 APP 中做好群组和群成员信息缓存,查询群组和群成员信息时都从本地缓存中访问。在群组或者群成员信息有变化时,SDK 会告诉注册的观察者,此时,第三方 APP 可更新缓存,并刷新界面。
实现流程
本章节通过群主、管理员、普通成员之间的交互为例,介绍群组管理的实现流程。
创建群组
通过调用 createTeam
方法创建群组,创建者即为该群群主。
参数说明:
参数 | 说明 |
---|---|
fields | 群组预设信息,key 为数据字段,value 为对应的值,该值类型必须和 field 中定义的 fieldType 一致 |
type | 群组类型Advanced 创建高级群,高级群拥有完善的成员权限体系及管理功能。为避免产生问题,不建议使用其他取值。 |
postscript | 邀请入群的附言。如果是创建临时群,该参数无效 |
members | 邀请加入的成员帐号列表 |
antiSpamConfig | 内容审核相关配置参数 |
创建群、修改群信息时的域定义,具体请参见TeamFieldEnum
枚举常量。
示例代码:
// 群组类型
TeamTypeEnum type = TeamTypeEnum.Advanced;
// 创建时可以预设群组的一些相关属性。
// fields 中,key 为数据字段,value 对对应的值,该值类型必须和 field 中定义的 fieldType 一致
HashMap<TeamFieldEnum, Serializable> fields = new HashMap<TeamFieldEnum, Serializable>();
fields.put(TeamFieldEnum.Name, teamName);
fields.put(TeamFieldEnum.Introduce, teamIntroduce);
fields.put(TeamFieldEnum.VerifyType, verifyType);
NIMClient.getService(TeamService.class).createTeam(fields, type, "", accounts)
.setCallback(new RequestCallback<Team> { ... });
加入群组
加入群组可以通过以下两种方式:
- 用户接受邀请入群。
- 用户主动申请入群。
邀请入群
邀请入群的权限可以通过 InviteMode
来定义,设为 Manager
,那么仅限群主和管理员可以邀请人进群;设为 All
,那么群组内的所有人都可以邀请人进群。
通过调用 addMembersEx
方法邀请其他用户进入群组。
- 若群组的被邀请模式
BeInviteMode
为NoAuth
,那么无需验证,其他用户可直接加入群组。 - 若群组的被邀请模式
BeInviteMode
为NeedAuth
,那么需要被邀请用户同意才能加入群组。
如果在被邀请成员中存在成员拥有的群组数量已达上限,则会返回失败成员的账号列表。
参数说明:
参数 | 说明 |
---|---|
teamId | 群ID |
accounts | 邀请入群的用户账号列表 |
customInfo | 自定义扩展字段,不需要的话设置为空 ,最长512字符 |
msg | 邀请附言,不需要的话设置为空 |
- 发起邀请后,被邀请用户会收到
SystemMessage
系统通知,其通知类型为TeamInvite
。 - 被邀请用户可以调用
acceptInvite
方法接受入群邀请,接受即入群。所有群成员会收到群组通知消息(消息类型为MsgTypeEnum.notification
),触发事件为AcceptInvite
。 - 也可以调用
declineInvite
方法拒绝入群邀请。拒绝后,邀请者会收到SystemMessage
系统通知,其通知类型为DeclineTeamInvite
。
示例代码:
NIMClient.getService(TeamService.class).addMembersEx(teamId, accounts, "邀请您加入群组")
.setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
// 返回onSuccess,表示拉人不需要对方同意,且对方已经入群成功了
}
@Override
public void onFailed(int code) {
// 返回onFailed,并且返回码为810,表示发出邀请成功了,但是还需要对方同意
}
@Override
public void onException(Throwable exception) {
...
}
});
//接受邀请
NIMClient.getService(TeamService.class).acceptInvite(teamId, inviter).setCallback(...);
//拒绝邀请
NIMClient.getService(TeamService.class).declineInvite(teamId, inviter, "").setCallback(callback);
申请入群
通过调用 applyJoinTeam
方法申请加入群组。
- 若群组的加入模式
VerifyType
为Free
,那么无需验证,其他用户可直接加入群组。 - 若群组的加入模式
VerifyType
为Apply
,那么需要群主或者群管理员同意才能加入群组。 - 若群组的加入模式
VerifyType
为Private
,那么该群组不接受入群申请,仅能通过邀请方式入群。
直接加入群或者进入等待验证状态时,返回群组信息。
参数说明:
参数 | 说明 |
---|---|
tid | 群ID |
postscript | 申请附言 |
- 当用户发起入群申请后,该群群主和管理员会收到
SystemMessage
系统通知,其通知类型为ApplyJoinTeam
。 - 群主和群管理员可以调用
passApply
方法接受入群申请,接受即入群。所有群成员会收到群组通知消息(消息类型为MsgTypeEnum.notification
),触发事件为PassTeamApply
。 - 群主和群管理员也可以调用
rejectApply
方法拒绝入群申请。拒绝后,申请者会收到SystemMessage
系统通知,其通知类型为RejectTeamApply
。
示例代码:
NIMClient.getService(TeamService.class).applyJoinTeam(team.getId(), null).setCallback(new RequestCallback<Team>() {
@Override
public void onSuccess(Team team) {
// 申请入群无需验证,直接申请成功
}
@Override
public void onFailed(int code) {
//仅仅是申请成功,code 808
if (code == ResponseCode.RES_TEAM_APPLY_SUCCESS) {
applyJoinButton.setEnabled(false);
ToastHelper.showToast(AdvancedTeamJoinActivity.this, R.string.team_apply_to_join_send_success);
}
// 已经在群里,code 809
else if (code == ResponseCode.RES_TEAM_ALREADY_IN) {
applyJoinButton.setEnabled(false);
ToastHelper.showToast(AdvancedTeamJoinActivity.this, R.string.has_exist_in_team);
// 群人数已达上限
} else if (code == ResponseCode.RES_TEAM_LIMIT) {
applyJoinButton.setEnabled(false);
ToastHelper.showToast(AdvancedTeamJoinActivity.this, R.string.team_num_limit);
} else {
ToastHelper.showToast(AdvancedTeamJoinActivity.this, "failed, error code =" + code);
}
}
@Override
public void onException(Throwable exception) {
// error
}
});
//同意入群申请
NIMClient.getService(TeamService.class).passApply(teamId, account).setCallback(...);
//拒绝入群申请
NIMClient.getService(TeamService.class).rejectApply(teamId, account, "您已被拒绝").setCallback(...);
转让群组
只有群主才有转让群组的权限。
通过调用 transferTeam
方法将群组转让给其他成员。
- 转让群后, 群主身份转移,所有群成员会收到群组通知消息(消息类型为
MsgTypeEnum.notification
),触发事件为TransferOwner
。 - 如果转让群的同时离开群, 那么相当于同时调用
quitTeam
主动退群。所有群成员会收到群组通知消息(消息类型为MsgTypeEnum.notification
),触发事件为LeaveTeam
。
参数说明:
参数 | 说明 |
---|---|
tid | 群ID |
account | 转让后的群主账号 |
quit | 转让群的同时是否退出该群 true:退出 false:不退出,身份变为普通群成员 |
示例代码:
// false表示群主转让后不退群
NIMClient.getService(TeamService.class).transferTeam(teamId, account, false)
.setCallback(new RequestCallback<List<TeamMember>>() {
@Override
public void onSuccess(List<TeamMember> members) {
// 群转移成功
}
@Override
public void onFailed(int code) {
// 群转移失败
}
@Override
public void onException(Throwable exception) {
// 错误
}
});
退出群组
退出群组可以通过以下两种方式:
- 群主或群组管理员将用户踢出群组。
- 用户主动退群。
踢人出群
- 只有群主和管理员才能将成员踢出群组。
- 管理员不能踢群主和其他管理员。
通过调用 removeMember
方法将成员踢出群组。也可以调用removeMembers
方法批量移除群成员。
移除成员后,所有群成员会收到群组通知消息(消息类型为 MsgTypeEnum.notification
),触发事件为KickMember
。
参数说明:
参数 | 说明 |
---|---|
teamId | 群ID |
members | 被踢出的群成员账号列表 |
示例代码:
NIMClient.getService(TeamService.class).removeMembers(teamId, accountList).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
// 成功
}
@Override
public void onFailed(int code) {
// 失败
}
@Override
public void onException(Throwable exception) {
// 错误
}
});
主动退群
通过调用 quitTeam
方法主动退出群组。
除群主(需先转让群主)外,其他用户均可以直接主动退群。主动退群后, 所有群成员会收到群组通知消息(消息类型为 MsgTypeEnum.notification
),触发事件为LeaveTeam
。
示例代码:
NIMClient.getService(TeamService.class).quitTeam(teamId).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
// 退群成功
}
@Override
public void onFailed(int code) {
// 退群失败
}
@Override
public void onException(Throwable exception) {
// 错误
}
});
解散群组
只有群主才能解散群组。
通过调用 dismissTeam
方法解散群组。
解散群后, 所有群成员会收到群组通知消息(消息类型为 MsgTypeEnum.notification
),触发事件为DismissTeam
。
示例代码:
NIMClient.getService(TeamService.class).dismissTeam(teamId).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
// 解散群成功
}
@Override
public void onFailed(int code) {
// 解散群失败
}
@Override
public void onException(Throwable exception) {
// 错误
}
});
修改群组信息
修改群信息需要权限。若该群组的群信息修改权限(TeamUpdateModeEnum
)为 Manager
,那么只有群主和管理员才能修改群组信息;若为 All
,则群组内的所有人都可以修改群组信息。
可更新的群组属性请参见TeamFieldEnum
。
参数 | 类型 | 说明 |
---|---|---|
AllMute | TeamAllMuteModeEnum |
群禁言(群全员禁言),该字段只读,使用“群资料更新”接口更新该字段无效 |
Announcement | String | 群公告 |
BeInviteMode | TeamBeInviteModeEnum |
群被邀请模式:被邀请人的同意方式 |
Ext_Server_Only | String | 群扩展字段(仅服务端能够修改) |
Extension | String | 群扩展字段(客户端自定义信息) |
ICON | String | 群头像,群组头像若要上传到云信服务器上,则需要使用头像资源处理 |
Introduce | String | 群简介 |
InviteMode | TeamInviteModeEnum |
群邀请模式:谁可以邀请他人入群 |
Name | String | 群名 |
TeamExtensionUpdateMode | TeamExtensionUpdateModeEnum |
群资料扩展字段修改模式:谁可以修改群自定义属性(扩展字段) |
TeamUpdateMode | TeamUpdateModeEnum |
群资料修改模式:谁可以修改群资料 |
VerifyType | VerifyTypeEnum |
申请加入群组的验证模式 |
MaxMemberCount | int | 指定创建群组的最大群成员数量 |
undefined | String | 未定义的域 |
修改群组的单个属性信息
通过调用 updateTeam
方法修改群组的单个属性信息。
当用户更新群组信息后,所有群成员会收到群组通知消息(消息类型为 MsgTypeEnum.notification
),触发事件为UpdateTeam
。
参数说明:
参数 | 说明 |
---|---|
teamId | 群ID |
field | 待更新的域 |
value | 待更新的域的新值 该值类型必须和field中定义的fieldType一致 |
示例代码:
//以修改群公告为例
String announcement = "这是更新的群公告";
NIMClient.getService(TeamService.class).updateTeam(teamId, TeamFieldEnum.Announcement, announcement).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
// 成功
}
@Override
public void onFailed(int code) {
// 失败
}
@Override
public void onException(Throwable exception) {
// 错误
}
});
修改群组的多个属性信息
通过调用 updateTeamFields
方法批量修改群组的多个属性信息。
当用户更新群组信息后,所有群成员会收到群组通知消息(消息类型为 MsgTypeEnum.notification
),触发事件为UpdateTeam
。
参数说明:
参数 | 说明 |
---|---|
teamId | 群ID |
fields | 待更新的所有字段的新的资料,其中值类型必须和field中定义的fieldType一致 |
antiSpamConfig | 内容审核相关配置参数 |
示例代码:
// 以修改群组名字,介绍,公告为例
Map<TeamFieldEnum, Serializable> fieldsMap = new HashMap<>();
fieldsMap.put(TeamFieldEnum.Name, "新的名称");
fieldsMap.put(TeamFieldEnum.Introduce, "新的介绍");
fieldsMap.put(TeamFieldEnum.Announcement, "新的公告");
NIMClient.getService(TeamService.class).updateTeamFields(teamId,
fieldsMap).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void aVoid) {
// 成功
}
@Override
public void onFailed(int i) {
// 失败
}
@Override
public void onException(Throwable throwable) {
// 错误
}
});
查询群组信息
本地查询自己加入的所有群组
通过异步调用queryTeamList
方法或者同步调用queryTeamListBlock
从本地查询自己加入的所有群组。示例代码如下:
//异步调用
NIMClient.getService(TeamService.class).queryTeamList().setCallback(new RequestCallback<List<Team>>() {
@Override
public void onSuccess(List<Team> teams) {
// 获取成功,teams为加入的所有群组
}
@Override
public void onFailed(int i) {
// 获取失败
}
@Override
public void onException(Throwable throwable) {
// 获取异常
}
});
//同步调用
List<Team> teams = NIMClient.getService(TeamService.class).queryTeamListBlock();
查询自己加入的群组数量
通过调用queryTeamCountBlock
方法查询自己加入的群组数量。示例代码如下:
int queryTeamCountBlock();
查询指定群组
通过异步调用queryTeam
查询指定群组信息。
- 异步调用
queryTeam
时,如果本地没有该群组信息,则自动去服务器查询。 - 同步调用
queryTeamBlock
时,仅查询本地,不会去服务器请求。如果自己不在该群组中,接口返回的可能是过期信息,如需最新的,请调用searchTeam
方法去服务器查询。
示例代码如下:
//异步调用
NIMClient.getService(TeamService.class).queryTeam(teamId).setCallback(new RequestCallbackWrapper<Team>() {
@Override
public void onResult(int code, Team t, Throwable exception) {
if (code == ResponseCode.RES_SUCCESS) {
// 成功
} else {
// 失败,错误码见code
}
if (exception != null) {
// error
}
}
});
//同步调用
Team team = NIMClient.getService(TeamService.class).queryTeamBlock(teamId);
群组信息 SDK 本地存储说明:
-
解散群、退出群或者被移出群时,本地数据库会继续保留该群组信息,只是设置了无效标记,此时依然可以通过
queryTeam
接口查询该群组信息,只是isMyTeam
返回 false 。 如果用户手动清空全部本地数据,下次登录同步时,服务器将不同步无效的群组,用户将无法取得已退出群的群组信息。 -
群解散后,通过
searchTeam
接口从服务器查询结果将返回null
。
批量查询指定群组
通过异步调用queryTeamListById
方法或者同步调用queryTeamListByIdBlock
批量查询指定群组信息。
示例代码如下:
List<String> tids = getTids();
//异步查询群列表
NIMClient.getService(TeamService.class).queryTeamListById(tids).setCallback(new RequestCallback<List<Team>>() {
@Override
public void onSuccess(List<Team> result) {
//查询成功
}
@Override
public void onFailed(int code) {
//查询失败
}
@Override
public void onException(Throwable exception) {
//查询异常
}
});
//同步查询群列表
List<Team> teams = NIMClient.getService(TeamService.class).queryTeamListByIdBlock(tids);
从云端查询指定群组
- 通过调用
searchTeam
方法从云端获取指定的单个群组。示例代码如下:
// teamId为想要查询的群组ID
NIMClient.getService(TeamService.class).searchTeam(teamId).setCallback(new RequestCallback<Team>() {
@Override
public void onSuccess(Team team) {
// 查询成功,获得群组信息
}
@Override
public void onFailed(int code) {
// 失败
}
@Override
public void onException(Throwable exception) {
// 错误
}
});
- 通过调用
searchTeam
方法从云端批量获取指定的多个群组。示例代码如下:
NIMClient.getService(TeamService.class).searchTeam(idList).setCallback(new RequestCallback<TeamInfoResult>() {
@Override
public void onSuccess(TeamInfoResult teaminforesult) {
onSearchTeamsInfoSuccess(teaminforesult);
}
@Override
public void onFailed(int code) {
}
@Override
public void onException(Throwable exception) {
}
});
群组检索
- 通过调用
searchTeamIdByName
方法根据群名称搜索群组 ID。示例代码如下:
NIMClient.getService(TeamService.class).searchTeamIdByName("安卓").setCallback(new RequestCallbackWrapper<List<String>>() {
@Override
public void onResult(int code, List<String> result, Throwable exception) {
if (code == ResponseCode.RES_SUCCESS) {
// 成功
} else {
// 失败,错误码见code
}
if (exception != null) {
// error
}
}
});
- 通过调用
searchTeamsByKeyword
方法搜索与关键字匹配的所有群。
示例代码如下:
NIMClient.getService(TeamService.class).searchTeamsByKeyword("群名称搜索关键字").setCallback(new RequestCallback<List<Team>>() {
@Override
public void onSuccess(List<Team> result) {
//查询成功
}
@Override
public void onFailed(int code) {
//查询失败
}
@Override
public void onException(Throwable exception) {
//查询异常
}
});
API 参考
API |
说明 |
---|---|
createTeam |
创建群组 |
addMembersEx |
邀请入群 |
acceptInvite |
接受入群邀请 |
declineInvite |
拒绝入群邀请 |
applyJoinTeam |
申请入群 |
passApply |
接受入群申请 |
rejectApply |
拒绝入群申请 |
removeMember |
踢人出群 |
removeMembers |
批量踢人出群 |
quitTeam |
主动退群 |
transferTeam |
转让群组 |
dismissTeam |
解散群组 |
updateTeam |
修改群组的单个属性信息 |
updateTeamFields |
批量修改群组的多个属性信息 |
queryTeamList |
从本地查询自己加入的所有群组(异步接口) |
queryTeamListBlock |
从本地查询自己加入的所有群组(同步接口) |
queryTeamCountBlock |
查询自己加入的群组数量 |
queryTeam |
查询指定群组信息(异步接口) |
queryTeamBlock |
查询指定群组信息(同步接口) |
queryTeamListById |
批量查询指定群组信息(异步接口) |
queryTeamListByIdBlock |
批量查询指定群组信息(同步接口) |
searchTeam |
从云端获取指定的单个群组 |
searchTeam |
从云端批量获取指定的多个群组 |
searchTeamIdByName |
根据群名称查询群组 ID |
searchTeamsByKeyword |
搜索与关键字匹配的所有群 |