超大群组功能

超大群组功能概述

网易云通信 SDK 提供了超大群群聊功能。

超大群是针对大规模群聊场景的功能。目前支持不超过5000人的群聊。由于超大群场景较为特殊,并不能支持所有高级群提供的管理功能。目前超大群仅支持群主与普通成员两种身份。

群组消息

群聊消息

超大群聊消息收发和管理和单人聊天基本完全相同,仅在 SessionTypeEnum 上做了区分,同时发送消息服务变成了SuperTeamService, 接收消息SuperTeamServiceObserver, 详见消息收发节。

NIMClient.getService(SuperTeamService.class).sendMessage(textMessage, false);

Observer<List<IMMessage>> incomingMessageObserver =
    new Observer<List<IMMessage>>() {
        @Override
        public void onEvent(List<IMMessage> messages) {
            // 处理新收到的消息,为了上传处理方便,SDK 保证参数 messages 全部来自同一个聊天对象。
        }
    }
NIMClient.getService(SuperTeamServiceObserver.class)
        .observeReceiveMessage(incomingMessageObserver, true);

强推消息

超大群消息支持设置强制推送。强制推送优先级最高,

1、打开强推开关,即使关闭消息提醒,依然能收到通知栏提醒,但是声音和震动跟随本机设置。

2、打开强推开关,即使设置了 桌面端在线时不推送,依然能收到通知栏提醒。

3、无论是否打开强推开关,设置了强推通知文本内容并且位于强推列表中的成员(若强推列表为 null,则表示本群所有成员),收到的消息提醒均显示强推通知文本。

4、强推列表可以配置需要强制推送的群成员,若为 null ,则表示该群所有群成员均收到强制推送消息。

5、打开强推开关,也打开免打扰设置。有通知栏提醒,但是没有声音和震动。

MemberPushOption 接口说明

返回值 MemberPushOption接口 说明
List getForcePushList() 返回强制推送的账号列表
String getForcePushContent() 返回强制推送的文案
boolean isForcePush() 返回是否强制推送
void setForcePush(boolean forcePush) 设置是否强推。
针对 forcePushList 里的帐号,
false 为不强推,true 为强推,默认为 true。
对于 forcePushList 中的用户,推送文案为 forcePushContent;
对于不在 forcePushList 中的用户,推送文案为 pushContent;
针对在 forcePushList 中的账号:
isForcePush 为true 时,推送文案中不会包含发送者 nick,直接为 forcePushContent;
isForcePush 为 false 时,推送文案中目前包含了发送者 nick(暂定),即为 fromNick:forcePushContent
void setForcePushList(List forcePushList) 设置强推列表,
填 null 表示强推给该会话所有成员,
不为 null 时最大上限账号为100个
void setForcePushContent(String forcePushContent) 强推文案(可扩展为区别与普通推送的推送文案),目前限制为500字以内
// 该帐号为示例,请先注册
String account = "testAccount";
// 群聊才有强推消息
SessionTypeEnum sessionType = SessionTypeEnum.Team;
String text = "指定推送消息";
// 创建一个文本消息
IMMessage message = MessageBuilder.createTextMessage(account, sessionType, text);
// 配置推送
MemberPushOption memberPushOption = new MemberPushOption();
// 开启强制推送
memberPushOption.setForcePush(true);
// 设置强推文案
memberPushOption.setForcePushContent(message.getContent());

List<String> pushList = new ArrayList<>();
pushList.add("account1");
pushList.add("account2");
// 设置指定推送列表
memberPushOption.setForcePushList(pushList);

message.setMemberPushOption(memberPushOption);
message.setPushContent(pushContentEdit.getText().toString());

NIMClient.getService(SuperTeamService.class).sendMessage(message, false).setCallback(
  new RequestCallbackWrapper<Void>() {
    @Override
    public void onResult(int code, Void result, Throwable exception) {
      if (code == 200) {
        showToast("发送强推消息成功");
      } else {
        showToast("发送强推消息失败" + code);
      }
    }
  });

消息撤回

SuperTeamService新增接口

返回值 SuperTeamService部分接口 说明
InvocationFuture revokeMessage(IMMessage ) 消息撤回 ,默认没有第三方推送(包括IOS平台的推送),参考{@link SuperTeamService#revokeMessage(IMMessage, String, Map)}
InvocationFuture revokeMessage(IMMessage message, String, Map)
//撤回消息
NIMClient.getService(SuperTeamService.class).revokeMessage(message);

群组管理

获取群组

SDK 提供了获取自己加入的所有群的列表的接口

1. 获取我加入的所有群组

异步版本:

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

同步版本

/**
 * 获取自己加入的群的列表(同步版本)
 *
 * @return 自己加入的群的列表
 */
public List<SuperTeam> queryTeamListBlock();

SuperTeam函数说明:部分参数预留

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

异步请求示例:

NIMClient.getService(SuperTeamService).queryTeamList().setCallback(new RequestCallback<List<Team>>() {
    @Override
    public void onSuccess(List<SuperTeam> teams) {
        // 获取成功,teams为加入的所有群组
    }

    @Override
    public void onFailed(int i) {
         // 获取失败,具体错误码见i参数
    }

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

同步请求示例:

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

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

创建群组

网易云通信超大群组创建:由服务器API创建。

邀请加入群组

所有人都可以拉人入群,如果在被邀请成员中存在成员的群组数量已达上限,则会返回这部分失败成员的账号。

/**
 * 添加成员
 *
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<List<String>> addMembers(String teamId, List<String> accounts);
参数 说明
teamId 群组ID
accounts 待加入的群成员帐号列表
NIMClient.getService(SuperTeamService).addMembers(teamId, accounts)
    .setCallback(new RequestCallback<Void>() {
            @Override
            public void onSuccess(Void param) {
                // 返回onSuccess,表示拉人不需要对方同意,且对方已经入群成功了
            }

            @Override
            public void onFailed(int code) {
                // 返回onFailed
            }

            @Override
            public void onException(Throwable exception) {
                ...
            }
        });

用户入群后,在收到之后的第一条消息时,群内所有成员(包括入群者)会收到一条入群消息,附件类型为 MemberChangeAttachment。若通知类型为NotificationType#SUPER_TEAM_INVITE,可以通过 MemberChangeAttachment#getExtension 获取服务器设置的扩展字段。

踢人出群

仅拥有者可以踢人,群内所有成员(包括被踢者)会收到一条消息类型为 notification 的 IMMessage,类型为 NotificationType#SUPER_TEAM_KICK, 附件类型为 MemberChangeAttachment。可以通过 MemberChangeAttachment#getExtension 获取服务器设置的扩展字段。

/**
 * 移除成员,只有群主有此权限
 *
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> removeMember(String teamId, String member);

/**
 * 批量移出群成员,只有群主有权限
 *
 * @param teamId  群ID
 * @param members 被踢出的成员帐号列表
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> removeMembers(String teamId, List<String> members);
参数 说明
teamId 群ID
member 被踢出的成员帐号
// teamId表示群ID,account表示被踢出的成员帐号
NIMClient.getService(SuperSuperTeamService.class).removeMember(teamId, account).setCallback(new RequestCallback<Void>() {
    @Override
    public void onSuccess(Void param) {
       // 成功
    }

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

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

主动退群

普通群群主可以退群,若退群,该群没有群主。其他用户均可以主动退群。退群后,群内所有成员(包括退出者)会收到一条消息类型为 notification 的 IMMessage,类型为 NotificationType#SUPER_TEAM_LEAVE,附件类型为 MemberChangeAttachment

/**
 * 退出群
 *
 * @param teamId 群ID
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> quitTeam(String teamId);
NIMClient.getService(SuperTeamService.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 查出来该群成员资料,只是 isMyTeam 将返回 false 。

1. 获取群组所有成员

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

2. 根据群 ID 和成员帐号获取群成员

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

异步版本:

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

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

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

异步版本示例:

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

同步版本示例:

SuperTeamMember member = NIMClient.getService(SuperTeamService.class).queryTeamMemberBlock(teamId, account);

3. 根据群 ID 和分页取群成员

/**
 * 分页获取指定群的成员信息列表. <br>
 * 该操作有可能只是从本地数据库读取缓存数据,也有可能会从服务器同步新的数据, 因此耗时可能会比较长。
 *
 * @param teamId 群ID
 * @param offset 偏移位置
 * @param limit  获取条数,每次最多200
 * @return InvocationFuture 可以设置回调函数,如果成功,参数为群的成员信息列表
 */
InvocationFuture<List<SuperTeamMember>> queryMemberListByPage(String teamId, int offset, int limit);

群组资料管理

查询群组资料

1. 从本地数据库中查询群资料

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

异步版本:

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

同步版本:

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

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

异步接口示例:

NIMClient.getService(SuperTeamService.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
SuperTeam team = NIMClient.getService(SuperTeamService.class).queryTeamBlock(teamId);

2. 从服务器上查询群资料

用户可以直接从服务器上查询群资料

/**
 * 从服务器上查询群资料信息
 *
 * @param teamId 群ID
 * @return
 */
InvocationFuture<SuperTeam> searchTeam(String teamId);
// teamId为想要查询的群组ID
NIMClient.getService(SuperTeamService.class).searchTeam(teamId).setCallback(new RequestCallback<SuperTeam>() {
    @Override
    public void onSuccess(SuperTeam team) {
        // 查询成功,获得群组资料
    }

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

    @Override
    public void onException(Throwable exception) {
       // 错误
    }
});
错误码 说明
803 查询的群id不存在

群资料 SDK 本地存储说明:

1. 解散群、退群或者被移出群时,本地数据库会继续保留这个群资料,只是设置了无效标记,此时依然可以通过 queryTeam 查出来该群资料,只是 isMyTeam 返回 false 。 如果用户手动清空全部本地数据,下次登录同步时,服务器不会将无效的群资料同步过来,将无法取得已退出群的群资料。

2. 群解散后,通过 searchTeam 接口从服务器查询将返回 null 。

编辑群组资料

1. 单个群属性更新

每次仅修改群的一个属性,可修改的属性查看 TeamFieldEnum ,注意: 其中的 Ext_Server_Only 群服务器扩展字段,仅限服务端修改。

更新的value值,对应的数据类型,同样查看 TeamFieldEnum 。例如:群名 Name(ITeamService.TinfoTag.NAME, String.class),表示 value 值的数据类型为 String。验证类型 VerifyType(ITeamService.TinfoTag.JOIN_MODE, VerifyTypeEnum.class),表示 value 值的数据类型为VerifyTypeEnum。

TeamFieldEnum属性 说明 数据类型
Announcement 群公告 String
Ext_Server_Only 群扩展字段(仅服务端能够修改) String
Extension 群扩展字段(客户端自定义信息) String
ICON 群头像 String
Introduce 群简介 String
Name 群名 String

修改后,群内所有成员会收到一条消息类型为 notification 的 IMMessage,带有一个消息附件,类型为 UpdateTeamAttachment。如果注册了群组资料变化观察者,观察者也会收到通知,见监听群组资料变化

/**
 * 更新群组资料
 *
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> updateTeam(String teamId, TeamFieldEnum field, Serializable value);
参数 说明
teamId 群ID
field 待更新的域
value 待更新的域的新值 该值类型必须和field中定义的fieldType一致

以群公告为例

String announcement = "这是更新的群公告";
NIMClient.getService(SuperTeamService.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) {
        // 错误
    }
});

注意: 更新群头像请注意: 需要先调用 NosService#upload 方法,将头像图片成功上传到 nos。再将 nos 的 url 地址更新到群资料。

2. 批量更新群组资料

/**
 * 批量更新群组资料,可一次性更新多个字段的值。
 *
 * @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(SuperTeamService.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 可更新缓存,并刷新界面。

1. 监听群资料变化

/**
 * 群资料变动观察者通知。新建群和群更新的通知都通过该接口传递
 * @param observer 观察者, 参数为有更新的群资料列表
 * @param register true为注册,false为注销
 */
public void observeTeamUpdate(Observer<List<SuperTeam>> observer, boolean register);
返回值 SuperTeam接口 说明
String getAnnouncement() 获取群组公告
long getCreateTime() 获取群组的创建时间
String getCreator() 获取创建群组的用户帐号
String getExtension() 获取群组扩展配置
String getExtServer() 获取服务器设置的扩展配置
String getIcon() 获取群头像
String getId() 获取群组ID
String getIntroduce() 获取群组简介
int getMemberCount() 获取群组的总成员数
int getMemberLimit() 获取群组的成员人数上限
String getName() 获取群组名称
boolean isMyTeam() 获取自己是否在这个群里
boolean mute() 获取这个群收到新消息时要不要提醒的设置,废弃,使用getMessageNotifyType()替代
void setExtension(String extension) 设置群组扩展配置
// 创建群组资料变动观察者
Observer<List<SuperTeam>> teamUpdateObserver = new Observer<List<SuperTeam>>() {
    @Override
    public void onEvent(List<SuperTeam> teams) {
    }
};
// 注册/注销观察者
NIMClient.getService(SuperTeamServiceObserver.class).observeTeamUpdate(teamUpdateObserver, register);

2. 监听移除群的变化

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

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

修改自己的群昵称

修改自己的群昵称。

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

修改自己的群成员扩展字段

修改后,群成员会收到群成员资料变更通知

/**
 * 修改自己的群成员扩展字段(自定义属性, 最长32个字符)
 *
 * @param teamId    所在群组ID
 * @param extension 新的扩展字段(自定义属性)
 * @return InvocationFuture 可以设置回调函数,监听操作结果
 */
InvocationFuture<Void> updateMyMemberExtension(String teamId, String extension);
String extension = "1213";
NIMClient.getService(SuperTeamService.class).updateMyMemberExtension(teamId, extension)

监听群成员资料变化

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

1. 监听群成员资料变化


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

2. 监听移除群成员的变化

/**
 * 移除群成员的观察者通知。
 * @param observer 观察者, 参数为被移除的群成员
 * @param register true为注册,false为注销
 */
public void observeMemberRemove(Observer<SuperTeamMember> observer, boolean register);
// 移除群成员的观察者通知。
private Observer<SuperTeamMember> memberRemoveObserver = new Observer<SuperTeamMember>() {
    @Override
    public void onEvent(SuperTeamMember member) {
    }
};
// 注册/注销观察者
NIMClient.getService(SuperTeamServiceObserver.class).observeMemberRemove(memberRemoveObserver, register);