Android

群消息管理

更新时间: 2024/08/08 09:53:42

网易云信 NIM SDK 支持群组中的消息收发,群组相关操作的通知消息的接收,群消息强制推送以及群消息免打扰的设置。

群消息收发

群组中支持收发多种消息类型。

在创建/加入群组后,用户发送和接收消息的接口与单聊消息收发相同,区别在于会话类型(sessionType)的参数配置,选择 Team 即可。

SessionTypeEnum 参数说明

枚举常量 说明
P2P 单聊
Team 高级群
SUPER_TEAM 超大群
ChatRoom 聊天室
QChat 圈组
System 系统通知

具体消息收发的流程,请参见 消息收发

群组通知消息

NIM SDK 内置支持的会话消息类型(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 群信息更新

群通知消息解析步骤

  1. 通过 IMMessage.getMsgType 方法获取消息类型(MsgTypeEnum),若为 notification ,则为通知消息。
  2. IMMessage.getAttachment 方法获取的附件对象强类型转换为 NotificationAttachment
  3. 通过 NotificationAttachment.getType 方法获取具体的通知类型(NotificationType)。
  4. 根据对应的 NotificationTypeIMMessage.getAttachment 得到的附件对象强转为对应的附件类(见上方表格)。
  • 针对 MemberChangeAttachment,通过 getTargets 方法可以获取该事件的承受者。如 B 被踢出群,则通过 getTargets 可以获取到 B 的用户账号。
  • 针对 MuteMemberAttachment,其为 MemberChangeAttachment 的子类,可通过 getTargets 可以获取该事件的承受者,可通过 isMute 判断是禁言还是被解禁。
  • 针对 UpdateTeamAttachment,需要解析到具体是哪个群信息被更新。群整体禁言属于此类型。

解析被更新的群信息,示例代码如下:

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

群消息免打扰

SDK 支持对群消息设置免打扰。设置群消息免打扰后,该群组的消息不会触发在线消息提醒和离线推送的通知栏。

群消息的通知模式分为:

  • All:全部提醒(默认)
  • Manager:仅群主/管理员消息提醒,普通成员的消息免打扰
  • Mute:全部不提醒,群组所有成员的消息都免打扰

以上通知提醒指的是云信体系内的 离线推送在线提醒

群消息的通知模式不影响群消息的接收和未读数的变化。若将通知模式设置为免打扰,仍然能接收到群消息,未读数仍会变化,只是不会触发在线消息提醒和离线推送的通知栏。

设置免打扰

通过调用 muteTeam 来设置指定群组的消息免打扰。

参数说明:

参数 说明
teamId 群ID
notifyType 通知类型枚举
All:全部提醒(默认)
Manager:仅群主/管理员消息提醒,普通成员的消息免打扰
Mute:全部不提醒,群组所有成员的消息都免打扰

示例代码:

// 以设置 “仅管理员消息提醒,普通成员的消息免打扰” 为例
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 方法获取对应群组的消息是否处于免打扰状态。

群消息强制推送/提醒

云信 NIM SDK 支持对于群消息的强制推送/提醒功能。

当发送方设置了某条群消息的强制推送/提醒,群消息接收者即使设置了该群的群消息免打扰或全局的免打扰(具体参考全局推送免打扰),仍能接收到该条群消息的在线提醒或离线推送

通过消息体的指定成员推送选项字段 MemberPushOption 来实现。

MemberPushOption 接口说明:

参数 类型 说明
ForcePush Boolean 是否强制推送/提醒(仅针对 ForcePushList 中的账户),true 为强制推送(默认),false 为不强制推送
ForcePushList String 需要强推的成员列表
如果填 null,表示强制推送给该会话的所有成员,不为 null 时,最多可传入 100 个用户账号
ForcePushContent String 强制推送的文案,最大长度 500 字符,如果设置为 nil,则使用消息本身的推送文案(pushContent
  • 对于 ForcePushList 中的用户,推送文案使用 ForcePushContent;对于不在 ForcePushList 中的用户,推送文案使用 pushContent
  • ForcePushList 中的账户的推送文案又分两种情况.
    • ForcePush 为 true 时,推送文案中不会包含发送者前缀(nick),直接为 ForcePushContent
    • ForcePush 为 false 时,推送文案中目前包含了发送者的前缀(nick),即为 fromNick:ForcePushContent

示例代码如下:

// 该帐号为示例,请先注册
String account = "testAccount";
// 群聊才有强推消息
SessionTypeEnum sessionType = SessionTypeEnum.Team;
String text = "指定推送消息";
// 创建一个文本消息
IMMessage textMessage = MessageBuilder.createTextMessage(account, sessionType, text);

// 配置指定成员推送
MemberPushOption memberPushOption = new MemberPushOption();
// 开启强制推送
memberPushOption.setForcePush(true);
// 设置强推文案
memberPushOption.setForcePushContent(textMessage.getContent());
List<String> pushList = new ArrayList<>();
pushList.add("account1");
pushList.add("account2");
// 设置指定推送列表
memberPushOption.setForcePushList(pushList);
textMessage.setMemberPushOption(memberPushOption);

// 发送给对方
NIMClient.getService(MsgService.class).sendMessage(textMessage, false);

群消息已读回执

常见问题

IM SDK 在主动退群、被踢、解散群之后,会收到一条相应类型的群组通知消息,相关会话信息仍会保留,只是此后不再接收关于此群的消息。如果在收到相应的群通知消息之前将会话删除,则收到群通知消息后,SDK 会重建对应会话。因此,若需彻底删除群组会话,正确时机是收到相应类型的群通知消息之后。

此文档是否对你有帮助?
有帮助
去反馈
  • 群消息收发
  • 群组通知消息
  • 群通知消息解析步骤
  • 群消息免打扰
  • 设置免打扰
  • 查询免打扰状态
  • 群消息强制推送/提醒
  • 群消息已读回执
  • 常见问题