IM 即时通讯
Android
开发指南

群消息管理

更新时间: 2023/08/30 11:11:21

网易云信 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,需要解析到具体是哪个群信息被更新。群整体禁言属于此类型。

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

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

群消息免打扰

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 方法获取对应群的消息通知提醒模式。

群消息已读回执

API 参考

API
说明
muteTeam 设置指定群消息通知类型
getMessageNotifyType 获取对应群的消息通知提醒模式
fetchTeamMessageReceiptDetail (群消息发送方)查询单条群组消息在指定用户中的已读、未读账号列表
queryTeamMessageReceiptDetailBlock 从本地数据库查询单条群组消息在指定用户中的已读、未读账号列表(同步接口)
refreshTeamMessageReceipt (群消息发送方)批量刷新群组消息已读、未读的数量信息,没有异步回调
sendTeamMessageReceipt (群消息接收方)标记群组消息已读

常见问题

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

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