群组功能

群组功能概述

云信 SDK 提供了普通群 (TeamTypeEnum#Normal),以及高级群 (TeamTypeEnum#Advanced)两种形式的群聊功能。高级群拥有更多的权限操作,两种群聊形式在共有操作上保持了接口一致。

普通群没有权限操作,适用于快速创建多人会话的场景。每个普通群只有一个管理员。管理员可以对普通群进行增减员操作,普通成员只能对普通群进行增员操作。在添加新成员的时候,并不需要经过对方同意。

高级群在权限上有更多的限制,权限分为群主、管理员、以及群成员。2.4.0之前版本在添加成员的时候需要对方接受邀请;2.4.0版本之后,可以设定被邀请模式(是否需要对方同意)。高级群可以覆盖所有普通群的能力,建议开发者创建时选用高级群。

Team 函数说明:

返回值 Team函数 说明
String getAnnouncement() 获取群组公告
long getCreateTime() 获取群组的创建时间
String getCreator() 获取创建群组的用户帐号
String getExtension() 获取群组扩展配置。
String getExtServer() 获取服务器设置的扩展配置。
String getIcon() 获取群头像
String getId() 获取群组ID
String getIntroduce() 获取群组简介
int getMemberCount() 获取群组的总成员数
int getMemberLimit() 获取群组的成员人数上限
TeamMessageNotifyTypeEnum getMessageNotifyType() 获取群消息免打扰模式
TeamAllMuteModeEnum getMuteMode() 获取群禁言模式
String getName() 获取群组名称
TeamBeInvite
ModeEnum
getTeamBeInviteMode() 获取群被邀请模式:被邀请人的同意方式
TeamExtension
UpdateModeEnum
getTeamExtension
UpdateMode()
获取群资料扩展字段修改模式:谁可以修改群自定义属性(扩展字段)
TeamInviteModeEnum getTeamInviteMode() 获取群邀请模式:谁可以邀请他人入群
TeamUpdateModeEnum getTeamUpdateMode() 获取群资料修改模式:谁可以修改群资料
TeamTypeEnum getType() 获取群组类型
VerifyTypeEnum getVerifyType() 获取申请加入群组时的验证类型
boolean isAllMute() 是否群全员禁言
TeamAllMuteModeEnum getMuteMode() 获取全员禁言模式
boolean isMyTeam() 获取自己是否在这个群里
void setExtension(extension) 设置群组扩展配置。

创建群组

云信群组分为两类:普通群和高级群,两种群组的消息功能都是相同的,区别在于管理功能。普通群所有人都可以拉人入群,除群主外,其他人都不能踢人;高级群则拥有完善的成员权限体系及管理功能。创建群的接口相同,传入不同的类型参数即可。

/**
 * 创建一个群组
 *
 * @return InvocationFuture 可以设置回调函数,如果成功,参数为创建的群组资料
 */
InvocationFuture<CreateTeamResult> createTeam(Map<TeamFieldEnum, Serializable> fields, TeamTypeEnum type, String postscript, List<String> members);
参数 说明
fields 群组预设资料, key为数据字段,value对应的值,
该值类型必须和field中定义的fieldType一致。
type 要创建的群组类型
postscript 邀请入群的附言。如果是创建临时群,该参数无效
members 邀请加入的成员帐号列表

创建群时,会使用到的TeamFieldEnum枚举常量说明:

枚举 说明
Announcement 群公告
BeInviteMode 群被邀请模式:被邀请人的同意方式
Extension 群扩展字段(客户端自定义信息)
ICON 群头像
Introduce 群简介
InviteMode 群邀请模式:谁可以邀请他人入群
MaxMemberCount 指定创建群组的最大群成员数量 ,MaxMemberCount不能超过应用级配置的最大人数
Name 群名
TeamExtensionUpdateMode 群资料扩展字段修改模式:谁可以修改群自定义属性(扩展字段)
TeamUpdateMode 群资料修改模式:谁可以修改群资料
VerifyType 申请加入群组的验证模式

CreateTeamResult 说明:

参数 说明
team 创建成功后返回的team 对象
failedInviteAccounts 被邀请成员中群组数量已达上限的成员列表
// 群组类型
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> { ... });

获取群组

从本地获取所有群组

获取我加入的所有群组

异步版本:

/**
 * 获取自己加入的群的列表
 *
 * @return InvocationFuture 可以设置回调函数,如果成功,参数为自己加入的群的列表
 */
InvocationFuture<List<Team>> queryTeamList();

同步版本:

/**
 * 获取自己加入的群的列表(同步版本)
 *
 * @return 自己加入的群的列表
 */
public List<Team> 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) {
         // 获取失败,具体错误码见i参数
    }

    @Override
    public void onException(Throwable throwable) {
        // 获取异常
    }
});

同步请求示例:

// teams为加入的所有群组
List<Team> teams = NIMClient.getService(TeamService.class).queryTeamListBlock();

注意:这里获取的是所有我加入的群列表(退群、被移除群后,将不在返回列表中)。

自己所在群的数量

// 获取自己加入的群的数量
int queryTeamCountBlock();

获取指定群组

如果本地没有群组资料,则去服务器查询。如果自己不在这个群中,该接口返回的可能是过期资料,如需最新的,请调用 searchTeam 接口去服务器查询。 此外 queryTeam 接口也有同步版本: queryTeamBlock 。

异步版本:

/**
 * 查询群资料,如果本地没有群组资料,则去服务器查询。
 * 如果自己不在这个群中,该接口返回的可能是过期资料,如需最新的,请调用{@link #searchTeam(String)}接口
 *
 * @param teamId 群ID
 * @return InvocationFuture 可以设置回调函数,如果成功,参数为群资料
 */
InvocationFuture<Team> queryTeam(String teamId);

同步版本:

/**
 * 查询群资料(仅查询本地,不会去服务器请求)
 * 如果自己不在这个群中,该接口返回的可能是过期资料,如需最新的,请调用{@link #searchTeam(String)}接口
 *
 * @param teamId 群ID
 * @return 群资料
 */
Team queryTeamBlock(String teamId);

注意: 同步版本的查询群资料,仅查询本地,不会去服务器请求。

异步接口示例:

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
        }
    }
});

同步接口示例:

// teamId 为想要查询的群组 ID
Team team = NIMClient.getService(TeamService.class).queryTeamBlock(teamId);

群资料 SDK 本地存储说明:

批量获取指定群组

/**
 * 异步接口
 * 根据群id列表批量查询群信息
 *
 * @param tidList 群id列表
 * @return 可以设置回调函数,如果成功,参数为查询的群信息列表
 */
InvocationFuture<java.util.List<Team>> queryTeamListById(java.util.List<java.lang.String> tidList);

/**
 * 同步接口
 * 根据群id列表批量查询群信息
 *
 * @param tidList 群id列表
 */
java.util.List<Team> queryTeamListByIdBlock(java.util.List<java.lang.String> tidList);

获取指定类型群组

根据类型获取我加入的群组:

异步版本:

/**
 * 获取自己加入的指定类型群(讨论组/高级群)列表
 *
 * @param type 群类型
 * @return 可以设置回调函数,如果成功,参数为加入的指定类型群列表
 */
InvocationFuture<List<Team>> queryTeamListByType(TeamTypeEnum type);

同步版本:

/**
 * 获取自己加入的指定类型群(讨论组/高级群)列表(同步版本)
 *
 * @param type 群类型
 * @return 加入的指定类型群列表
 */
public List<Team> queryTeamListByTypeBlock(TeamTypeEnum type);
TeamTypeEnum属性 说明
Advanced 高级群,有完善的权限管理功能
Normal 讨论组,仅具有基本的权限管理功能,所有人都能加入,
仅群主可以踢人

异步版本示例:

// 以讨论组为例
NIMClient.getService(TeamService.class).queryTeamListByType(TeamTypeEnum.Normal).setCallback(new RequestCallback<List<Team>>() {
    @Override
    public void onSuccess(List<Team> teams) {
      // 成功
    }

    @Override
    public void onFailed(int i) {
      // 失败
    }

    @Override
    public void onException(Throwable throwable) {
        // 错误
    }
});

同步版本示例:

// 以高级群为例
List<Team> teams = NIMClient.getService(TeamService.class).queryTeamListByTypeBlock(TeamTypeEnum.Advanced);

获取指定类型群组数量

// 获取自己加入的指定类型群的数量
int queryTeamCountByTypeBlock(TeamTypeEnum type);

从云端获取指定群组

用户可以直接从服务器上获取群组信息:

/**
 * 从服务器上查询群资料信息
 *
 * @param teamId 群ID
 * @return
 */
InvocationFuture<Team> searchTeam(String teamId);
// 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) {
       // 错误
    }
});

解散群组

仅群主有这个权限。

/**
 * 解散群,只有群主有此权限
 *
 * @param teamId 群ID
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> dismissTeam(String teamId);
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) {
        // 错误
    }
});

群成员管理

入群操作

申请加入群组

/**
 * 用户申请加入群。
 *
 * @param tid        申请加入的群ID
 * @param postscript 申请附言
 * @return InvocationFuture 可以设置回调函数,如果成功,参数为群资料
 */
InvocationFuture<Team> applyJoinTeam(String tid, String postscript);
参数 说明
tid 申请加入的群ID
postscript 申请附言
NIMClient.getService(TeamService.class).applyJoinTeam(team.getId(), null).setCallback(new RequestCallback<Team>() {
    @Override
    public void onSuccess(Team team) {
        // 申请成功, 等待验证入群
    }

    @Override
    public void onFailed(int code) {
        // 申请失败
    }

    @Override
    public void onException(Throwable exception) {
        // error
    }
});
错误码 说明
808 申请已发出
809 已经在群里

验证入群申请

用户发出申请后,所有管理员都会收到一条系统通知,类型为 SystemMessageType#TeamApply,具体参数解释请参考系统通知章节。

仅管理员和群主有此权限。如果同意入群申请,群内所有成员(包括申请者)都会收到一条群通知消息。

/**
 * 通过用户的入群申请
 * 仅管理员和群主有此权限
 *
 * @return InvocationFuture 可以设置回调函数
 */
InvocationFuture<Void> passApply(String teamId, String account);
参数 说明
teamId 群ID
account 申请入群的用户ID
// teamId为申请加入的群组id, account为申请入群的用户id
NIMClient.getService(TeamService.class).passApply(teamId, account).setCallback(...);

仅管理员和群主有此权限。如果拒绝入群申请,申请者会收到一条系统通知,类型为 SystemMessageType#RejectTeamApply。具体参数说明见系统通知章节。任意一管理员操作后,其他管理员再操作都会失败。

/**
 * 拒绝用户的入群申请    
 * 仅管理员和群主有此权限
 *
 * @return InvocationFuture 可以设置回调函数
 */
InvocationFuture<Void> rejectApply(String teamId, String account, String reason);
参数 说明
teamId 群ID
account 申请入群的用户ID
reason 拒绝理由,选填
// teamId为申请加入的群组id, account为申请入群的用户id
NIMClient.getService(TeamService.class).rejectApply(teamId, account, "您已被拒绝").setCallback(...);

邀请加入群组

普通群所有人都可以拉人入群,SDK 2.4.0之前版本高级群仅管理员和群主可以邀请人入群, SDK 2.4.0及以后版本高级群在创建时可以设置群邀请模式,支持仅管理员或者所有人均可拉人入群。如果在被邀请成员中存在成员的群组数量已达上限,则会返回这部分失败成员的账号。

/**
 * 添加成员并设置自定义字段
 *
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<List<String>> addMembersEx(String teamId, List<String> accounts, String msg, String customInfo);
参数 说明
teamId 群组ID
accounts 待加入的群成员帐号列表
msg 邀请附言 ,不需要的话设置为空
customInfo 自定义扩展字段,不需要的话设置为空
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) {
                ...
            }
        });

验证入群邀请

被邀请的人会收到一条系统通知 SystemMessage,类型为 SystemMessageType#TeamInvite。用户接受该邀请后,才真正入群。

收到入群邀请后,可以选择接受或拒绝。接受邀请后,用户真正入群。如果拒绝邀请,对方会收到一条系统通知,类型为 SystemMessageType#DeclineTeamInvite

/**
 * 接受别人的入群邀请
 *
 * @return InvocationFuture 可以设置回调函数
 */
InvocationFuture<Void> acceptInvite(String teamId, String inviter);
参数 说明
teamId 群ID
inviter 邀请我的用户帐号
NIMClient.getService(TeamService.class).acceptInvite(teamId, inviter).setCallback(...);
/**
 * 拒绝别人的入群邀请通知
 *
 * @return InvocationFuture 可以设置回调函数
 */
InvocationFuture<Void> declineInvite(String teamId, String inviter, String reason);
参数 说明
teamId 群ID
inviter 邀请我的用户帐号
reason 拒绝理由,选填
NIMClient.getService(TeamService.class).declineInvite(teamId, inviter, "").setCallback(callback);

查询群成员入群邀请人

/**
 * 获取群成员入群邀请人(为空表示主动入群,没有邀请人)
 *
 * @param tid
 * @param accids 查询用户accid列表,最多两百
 * @return 返回用户的对应关系,key为accid value是inviteAccid
 */
InvocationFuture<Map<String, String>> getMemberInvitor(String tid,List<String> accids);
// accids表示查询的成员列表
NIMClient.getService(TeamService.class).getMemberInvitor(tid, accids).setCallback(
                    new RequestCallbackWrapper<Map<String, String>>() {

                        @Override
                        public void onResult(int code, Map<String, String> result, Throwable exception) {
                        // result 为对应关系
                        }
                    });

踢人出群

普通群仅群主可以踢人,高级群群主和管理员可以踢人,且管理员不能踢群主和其他管理员。踢人后,群内所有成员(包括被踢者)会收到一条消息类型为 notification 的 IMMessage,类型为 NotificationType#KickMember, 附件类型为 MemberChangeAttachment

/**
 * 移除成员,只有创建者有此权限
 *
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<java.lang.Void> removeMembers(java.lang.String teamId, java.util.List<java.lang.String> members);
参数 说明
teamId 群ID
members 被踢出的成员帐号列表
// teamId表示群ID,account表示被踢出的成员帐号
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) {
        // 错误
    }
});

主动退群

普通群群主可以退群,若退群,该群没有群主。高级群除群主(需先转让群主)外,其他用户均可以直接主动退群。退群后,群内所有成员(包括退出者)会收到一条消息类型为 notification 的 IMMessage,附件类型为 MemberChangeAttachment

/**
 * 退出群
 *
 * @param teamId 群ID
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> quitTeam(String teamId);
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) {
        // 错误
    }
});

获取群组成员

由于群组成员数据比较大,且除了进入群组成员列表界面外,其他地方均不需要群组成员列表的数据,因此 SDK 不会在登录时同步群组成员数据,而是按照按需获取的原则,当上层主动调用获取指定群的群组成员列表时,才判断是否需要同步。

群成员资料 SDK 本地存储说明: 当自己退群、或者被移出群时,本地数据库会继续保留这个群成员资料,只是设置了无效标记,此时依然可以通过 queryTeamMember 查出来该群成员资料,只是 isInTeam 将返回 false 。

TeamMember 说明:

返回值 TeamMember属性 说明
String getAccount() 群成员帐号
Map getExtension() 获取扩展字段
String getInvitorAccid() 获取入群邀请人,为空表示主动加入群
long getJoinTime() 获取群成员入群时间
String getTeamNick() 获取该用户在这个群内的群昵称
String getTid() 获取所在群ID
TeamMemberType getType() 群成员类型
boolean isInTeam() 该用户是否在这个群中
boolean isMute() 是否被禁言

获取群组成员列表

/**
 * 获取指定群的成员信息列表. <br>
 * 该操作有可能只是从本地数据库读取缓存数据,也有可能会从服务器同步新的数据, 因此耗时可能会比较长。
 *
 * @param teamId 群ID
 * @return InvocationFuture 可以设置回调函数,如果成功,参数为群的成员信息列表
 */
InvocationFuture<List<TeamMember>> queryMemberList(String teamId);
NIMClient.getService(TeamService.class).queryMemberList(teamId).setCallback(new RequestCallbackWrapper<List<TeamMember>>() {
            @Override
            public void onResult(int code, final List<TeamMember> members, Throwable exception) {
                ...
            }
        });

获取指定群组成员

如果本地群成员资料已过期, SDK 会去服务器获取最新的。

异步版本:

/**
 * 查询群成员资料。如果本地群成员资料已过期会去服务器获取最新的。
 *
 * @param teamId  群ID
 * @param account 群成员帐号
 * @return InvocationFuture 可以设置回调函数,如果成功,参数为该群成员信息
 */
InvocationFuture<TeamMember> queryTeamMember(String teamId, String account);

同步版本(仅查询本地群资料):

/**
 * 查询群成员资料。(同步版本)仅查询本地群资料
 *
 * @param teamId  群ID
 * @param account 群成员帐号
 * @return 群成员信息
 */
TeamMember queryTeamMemberBlock(String teamId, String account);

异步版本示例:

NIMClient.getService(TeamService.class).queryTeamMember(teamId, account).setCallback(new RequestCallbackWrapper<TeamMember>() {
    @Override
    public void onResult(int code, TeamMember member, Throwable exception) {
        ...
    }
});

同步版本示例:

TeamMember member = NIMClient.getService(TeamService.class).queryTeamMemberBlock(teamId, account);

修改群成员资料

修改其他群成员资料

普通群不支持修改成员的群昵称。

对于高级群,群主可以修改所有人的群昵称。管理员只能修改普通群成员的群昵称。

/**
 * 群组管理员修改群内其他成员的群昵称。
 * 仅群管理员和群主有此权限
 *
 * @param teamId  所在群组ID
 * @param account 要修改的群成员帐号
 * @param nick    新的群昵称
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> updateMemberNick(String teamId, String account, String nick);
// teamId表示所在群组ID,account表示要修改的群成员帐号,nickname表示新的群昵称
NIMClient.getService(TeamService.class).updateMemberNick(teamId, account, nickname).setCallback(new RequestCallback<Void>() {
    @Override
    public void onSuccess(Void param) {
        // 成功
    }

    @Override
    public void onFailed(int code) {
        // 失败
    }

    @Override
    public void onException(Throwable exception) {
        // 错误
    }
});

修改自己的群昵称

/**
 * 修改自己的群昵称
 *
 * @param teamId 所在群组ID
 * @param nick   新的群昵称
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> updateMyTeamNick(String teamId, String nick);
// test为修改后自己的群昵称
NIMClient.getService(TeamService.class).updateMyTeamNick(teamId, "test")

修改自身扩展字段

/**
 * 修改自己的群成员扩展字段(自定义属性)
 *
 * @param teamId    所在群组ID
 * @param extension 新的扩展字段(自定义属性)
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> updateMyMemberExtension(String teamId, Map<String, Object> extension);
Map<String, Object> extension = new HashMap<>();
extension.put("ext","newExt");
NIMClient.getService(TeamService.class).updateMyMemberExtension(teamId, ext)

监听群成员变化

由于获取群成员资料需要跨进程异步调用,开发者最好能在第三方 APP 中做好群成员资料缓存,查询群成员资料时都从本地缓存中访问。在群成员资料有变化时,SDK 会告诉注册的观察者,此时,第三方 APP 可更新缓存,并刷新界面。

/**
 * 群成员资料变化观察者通知。
 *     上层APP如果管理了群成员资料的缓存,可通过此接口更新缓存。
 * @param observer 观察者, 参数为有更新的群成员资料列表
 * @param register true为注册,false为注销
 */
public void observeMemberUpdate(Observer<List<TeamMember>> observer, boolean register);
// 群成员资料变化观察者通知。群组添加新成员,成员资料变化会收到该通知。
// 返回的参数为有更新的群成员资料列表。
Observer<List<TeamMember>> memberUpdateObserver = new Observer<List<TeamMember>>() {
    @Override
    public void onEvent(List<TeamMember> members) {
    }
};
// 注册/注销观察者
NIMClient.getService(TeamServiceObserver.class).observeMemberUpdate(memberUpdateObserver, register);
/**
 * 移除群成员的观察者通知。
 * @param observer 观察者, 参数为被移除的群成员
 * @param register true为注册,false为注销
 */
public void observeMemberRemove(Observer<TeamMember> observer, boolean register);
// 移除群成员的观察者通知。
private Observer<TeamMember> memberRemoveObserver = new Observer<TeamMember>() {
    @Override
    public void onEvent(TeamMember member) {
    }
};
// 注册/注销观察者
NIMClient.getService(TeamServiceObserver.class).observeMemberRemove(memberRemoveObserver, register);

群主转让

高级群群主可以将群的群主权限转给群内的其他成员,转移后,被转让者变为新的群主,原群主变为普通成员。原群主还可以选择在转让的同时,直接退出该群。

/**
 * 群主将群的群主权限转给另外一个人,转移后,另外一个人成为群主。
 * 原群主变成普通成员。若参数quit为true,原群主直接退出该群。
 *
 * @return InvocationFuture 可以设置回调函数,如果成功,视参数quit值:
 * quit为false:参数仅包含原群主和当前群主的(即操作者和account),权限已被更新。
 * quit为true: 参数为空。
 */
InvocationFuture<List<TeamMember>> transferTeam(String tid, String account, boolean quit);
参数 说明
tid 群ID
account 新任群主的用户帐号
quit 转移时是否要同时退出该群
// 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) {
        // 错误
    }
});

添加管理员

高级群中,群主可以增加管理员。操作完成后,群内所有成员都会收到一条消息类型为 notification 的 IMMessage,附件类型为 MemberChangeAttachment

/**
 * 群主添加管理员 
 * 仅群主有此权限
 *
 * @param teamId   群ID
 * @param accounts 待提升为管理员的用户帐号列表
 * @return InvocationFuture 可以设置回调函数,如果成功,参数为新增的群管理员列表
 */
InvocationFuture<List<TeamMember>> addManagers(String teamId, List<String> accounts);
参数 说明
teamId 群ID
accounts 待提升为管理员的用户帐号列表
InvocationFuture 可以设置回调函数,如果成功,参数为被提升的群成员列表
(权限已被升为Manager)。
// teamId 操作的群id, accountList为待提升为管理员的用户帐号列表
NIMClient.getService(TeamService.class).addManagers(teamId, accountList).setCallback(new RequestCallback<List<TeamMember>>() {
    @Override
    public void onSuccess(List<TeamMember> managers) {
        // 添加群管理员成功
    }

    @Override
    public void onFailed(int code) {
        // 添加群管理员失败
    }

    @Override
    public void onException(Throwable exception) {
        // 错误
});

移除管理员

高级群中,群主可以移除管理员。操作完成后,群内所有成员都会收到一条消息类型为 notification 的 IMMessage,附件类型为 MemberChangeAttachment

/**
 * 群主撤销管理员权限 
 * 仅群主有此权限
 *
 * @param teamId   群ID
 * @param managers 待撤销的管理员的帐号列表
 * @return InvocationFuture 可以设置回调函数,如果成功,参数为被撤销的群成员列表(权限已被降为Normal)。
 */
InvocationFuture<List<TeamMember>> removeManagers(String teamId, List<String> managers);
参数 说明
teamId 群ID
managers 待撤销的管理员的帐号列表
InvocationFuture 可以设置回调函数,如果成功,参数为被撤销的群成员列表
(权限已被降为Normal)。
// teamid为群id, accountList为待撤销的管理员的账号列表
NIMClient.getService(TeamService.class).removeManagers(teamId, accountList).setCallback(new RequestCallback<List<TeamMember>>() {
    @Override
    public void onSuccess(List<TeamMember> members) {
        // 移除群管理员成功
    }

    @Override
    public void onFailed(int code) {
        // 移除群管理员失败
    }

    @Override
    public void onException(Throwable exception) {
        // 错误
    }
});

禁言

禁言指定成员

/**
 * 禁言、解除禁言
 *
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> muteTeamMember(String teamId, String account, boolean mute);
参数 说明
teamId 群组ID
account 被禁言、被解除禁言的账号
mute true表示禁言,false表示解除禁言
// 以禁言为例
NIMClient.getService(TeamService.class).muteTeamMember(teamId, account, true).setCallback(new RequestCallback<Void>() {
    @Override
    public void onSuccess(Void param) {
        // 成功
    }

    @Override
    public void onFailed(int code) {
        // 失败
    }

    @Override
    public void onException(Throwable exception) {
        // 错误
    }
});

群整体禁言

将整个群禁言,该操作仅群主或者管理员有权限。禁言操作成功之后,会回调群更新接口。

/**
 * 对整个群禁言、解除禁言,对普通成员生效,只有群组、管理员有权限
 *
 * @param teamId 群组 ID
 * @param mute   true表示禁言,false表示解除禁言
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> muteAllTeamMember(String teamId, boolean mute);
参数 说明
teamId 群组ID
mute true表示禁言,false表示解除禁言
NIMClient.getService(TeamService.class).muteAllTeamMember(teamId, true));

查询被禁言情况

/**
 * 查询被禁言群成员列表
 * 该操作,只返回调用TeamService#muteTeamMember(String, String, boolean) 禁言的用户。
 *
 * @param teamId    群ID
 * @return 群成员信息列表
 */
List<TeamMember> queryMutedTeamMembers(String teamId);
// members表示被禁言的成员列表
List<TeamMember> members = NIMClient.getService(TeamService.class).queryMutedTeamMembers(teamId);

可以通过 Team#getMuteModeTeam#isAllMute 获取对应的情况。

可以通过 TeamMember - isMute()获取。

注意:当被整体禁言后,但未被 禁言指定成员muteTeamMember 方法禁言过,则 TeamMember - isMute() 仍为 false。

群资料管理

编辑群组资料

可修改的属性详见下方 TeamFieldEnum,注意: 其中的 Ext_Server_Only 群服务器扩展字段,仅限服务端修改。

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
undefined 未定义的域
VerifyType 申请加入群组的验证模式 VerifyTypeEnum
MaxMemberCount 指定创建群组的最大群成员数量 int

编辑单个资料

/**
 * 更新群组资料
 *
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> updateTeam(String teamId, TeamFieldEnum field, Serializable value);
参数 说明
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) {
        // 错误
    }
});

编辑多个资料

/**
 * 批量更新群组资料,可一次性更新多个字段的值。
 *
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> updateTeamFields(String teamId, Map<TeamFieldEnum, Serializable> fields);
参数 说明
teamId 群ID
fields 待更新的所有字段的新的资料,其中值类型必须和field中定义的fieldType一致
// 以名字,介绍,公告为例
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) {
        // 错误
    }
});

监听群组变化

由于获取群组资料需要跨进程异步调用,开发者最好能在第三方 APP 中做好群组资料缓存,查询群组资料时都从本地缓存中访问。在群组资料有变化时,SDK 会告诉注册的观察者,此时,第三方 APP 可更新缓存,并刷新界面。

监听群组更新

/**
 * 群资料变动观察者通知。新建群和群更新的通知都通过该接口传递
 * @param observer 观察者, 参数为有更新的群资料列表
 * @param register true为注册,false为注销
 */
public void observeTeamUpdate(Observer<List<Team>> observer, boolean register);
// 创建群组资料变动观察者
Observer<List<Team>> teamUpdateObserver = new Observer<List<Team>>() {
    @Override
    public void onEvent(List<Team> teams) {
    }
};
// 注册/注销观察者
NIMClient.getService(TeamServiceObserver.class).observeTeamUpdate(teamUpdateObserver, register);

监听群组移除

移除成功后,Team#isMyTeam 返回 false。

/**
 * 移除群的观察者通知。自己退群,群被解散,自己被踢出群时,会收到该通知
 * @param observer 观察者, 参数为被移除的群资料,此时群的isMyTeam接口返回false
 * @param register true为注册,false为注销
 */
public void observeTeamRemove(Observer<Team> observer, boolean register);
// 创建群组被移除的观察者。在退群,被踢,群被解散时会收到该通知。
Observer<Team> teamRemoveObserver = new Observer<Team>() {
    @Override
    public void onEvent(Team team) {
    // 由于界面上可能仍需要显示群组名等信息,因此参数中会返回 Team 对象。
    // 该对象的 isMyTeam 接口返回为 false。
    }
};
// 注册/注销观察者
NIMClient.getService(TeamServiceObserver.class).observeTeamRemove(teamRemoveObserver, register);

群组通知消息

群组通知的消息类型是 MsgTypeEnum.notification ,用户入群成功之后,任何关于群的变动(含自己入群的动作),云信服务器都会下发一条群通知消息。

目前支持触发群通知消息的事件有:

NotificationType枚举 附件类 事件说明
AcceptInvite MemberChangeAttachment 接受邀请后入群(需要被邀请人同意的模式)
InviteMember MemberChangeAttachment 邀请成员入群(无需被邀请人同意的模式)
AddTeamManager MemberChangeAttachment 添加管理员
KickMember MemberChangeAttachment 被踢出群
TransferOwner MemberChangeAttachment 转让群主
PassTeamApply MemberChangeAttachment 申请加入群成功
RemoveTeamManager MemberChangeAttachment 移除管理员
DismissTeam DismissAttachment 解散群
LeaveTeam LeaveTeamAttachment 退出群
MuteTeamMember MuteMemberAttachment 群内禁言/解禁
UpdateTeam UpdateTeamAttachment 群信息资料更新

群组通知解析步骤:

值得注意的是:

private static String buildUpdateTeamNotification(String tid, String account, UpdateTeamAttachment a) {
        StringBuilder sb = new StringBuilder();
        // 开始解析
        for (Map.Entry<TeamFieldEnum, Object> field : a.getUpdatedFields().entrySet()) {
            if (field.getKey() == TeamFieldEnum.Name) {
                sb.append("名称被更新为 " + field.getValue());
            } else if (field.getKey() == TeamFieldEnum.Introduce) {
                sb.append("群介绍被更新为 " + field.getValue());
            } else if (field.getKey() == TeamFieldEnum.Announcement) {
                sb.append(TeamHelper.getTeamMemberDisplayNameYou(tid, account) + " 修改了群公告");
            } else if (field.getKey() == TeamFieldEnum.VerifyType) {
                VerifyTypeEnum type = (VerifyTypeEnum) field.getValue();
                String authen = "群身份验证权限更新为";
                if (type == VerifyTypeEnum.Free) {
                    sb.append(authen + NimUIKit.getContext().getString(R.string.team_allow_anyone_join));
                } else if (type == VerifyTypeEnum.Apply) {
                    sb.append(authen + NimUIKit.getContext().getString(R.string.team_need_authentication));
                } else {
                    sb.append(authen + NimUIKit.getContext().getString(R.string.team_not_allow_anyone_join));
                }
            } else if (field.getKey() == TeamFieldEnum.Extension) {
                sb.append("群扩展字段被更新为 " + field.getValue());
            } else if (field.getKey() == TeamFieldEnum.Ext_Server_Only) {
                sb.append("群扩展字段(服务器)被更新为 " + field.getValue());
            } else if (field.getKey() == TeamFieldEnum.ICON) {
                sb.append("群头像已更新");
            } else if (field.getKey() == TeamFieldEnum.InviteMode) {
                sb.append("群邀请他人权限被更新为 " + field.getValue());
            } else if (field.getKey() == TeamFieldEnum.TeamUpdateMode) {
                sb.append("群资料修改权限被更新为 " + field.getValue());
            } else if (field.getKey() == TeamFieldEnum.BeInviteMode) {
                sb.append("群被邀请人身份验证权限被更新为 " + field.getValue());
            } else if (field.getKey() == TeamFieldEnum.TeamExtensionUpdateMode) {
                sb.append("群扩展字段修改权限被更新为 " + field.getValue());
            } else if (field.getKey() == TeamFieldEnum.AllMute) {
                TeamAllMuteModeEnum teamAllMuteModeEnum = (TeamAllMuteModeEnum) field.getValue();
                if (teamAllMuteModeEnum == TeamAllMuteModeEnum.Cancel) {
                    sb.append("取消群全员禁言");
                } else {
                    sb.append("群全员禁言");
                }
            } else {
                sb.append("群" + field.getKey() + "被更新为 " + field.getValue());
            }
            sb.append("\r\n");
        }
        if (sb.length() < 2) {
            return "未知通知";
        }
        return sb.delete(sb.length() - 2, sb.length()).toString();
    }

群消息免打扰

可以对某个群设置消息通知提醒模式,群消息通知提醒分为:

以上通知提醒指的是云信体系内的推送与消息提醒

设置免打扰

/**
 * 设置指定群消息通知类型,支持多端同步
 *
 * @param teamId 群组ID
 * @param notifyType   通知类型枚举
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> muteTeam(String teamId, TeamMessageNotifyTypeEnum notifyType);
参数 说明
teamId 群组ID
TeamMessageNotifyTypeEnum 消息提醒类型枚举,分别为全部提醒、仅管理员消息提醒、全部不提醒
// 以设置 “仅管理员消息提醒” 为例
TeamMessageNotifyTypeEnum type = TeamMessageNotifyTypeEnum.Manager;
NIMClient.getService(TeamService.class).muteTeam(teamId, type).setCallback(new RequestCallback<Void>() {
    @Override
    public void onSuccess(Void param) {
        // 设置成功
    }

    @Override
    public void onFailed(int code) {
        // 设置失败
    }

    @Override
    public void onException(Throwable exception) {
        // 错误
    }
});

查询免打扰状态

可通过从本地获取到的 TeamgetMessageNotifyType 接口获取对应群的消息通知提醒模式。

群组检索

用户可以查询到具有指定群名称的群ID的列表

/**
 * 通过群名称反查群组ID
 *
 * @param name 群组名称
 * @return 群ID列表
 */
InvocationFuture<List<String>> searchTeamIdByName(String name);
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
        }
    }
});

用户在客户端本地可以搜索与关键字匹配的所有群:

/**
 * 通过群名称反查群组ID
 *
 * @param name 群组名称
 * @return 群ID列表
 */
InvocationFuture<java.util.List<Team>> searchTeamsByKeyword(java.lang.String keyword);