IM 即时通讯
Android
开发指南

消息已读回执

更新时间: 2024/01/03 10:41:47

当发送方需要知道接收方是否已经阅读了自己发送的消息时,需要使用已读回执的功能。

网易云信 NIM Android SDK 的MsgServiceObserve类和MsgService接口,分别提供监听单聊/群聊消息已读回执和发送单聊消息已读回执的方法;发送群聊消息已读回执的方法所在的类为TeamService。调用发送已读回执的方法时,传入的消息即为需要显示为已读的消息。

本文的时序图可能因为网络问题显示异常。如显示异常,一般刷新当前页面即可正常显示。

单聊消息已读回执

uml diagram

前提条件

实现流程

  1. 消息发送方调用observeMessageReceipt方法注册已读回执观察者,监听已读回执。

    Observer回调函数的MessageReceipt接口的参数说明如下:

    返回值 MessageReceipt 接口 说明
    String getSessionId() 聊天对象的 ID
    long getTime() 该会话最后一条已读消息的时间,比该时间早的消息都视为已读

    示例代码:

    // 注册/注销观察者
    NIMClient.getService(MsgServiceObserve.class).observeMessageReceipt(messageReceiptObserver, register);
    private Observer<List<MessageReceipt>> messageReceiptObserver = new Observer<List<MessageReceipt>>() {
            @Override
            public void onEvent(List<MessageReceipt> messageReceipts) {
                receiveReceipt();
            }
    };
    
  2. (可选) 消息发送方在发送消息后,可调用isRemoteRead方法判断接收方是否已读。

  3. 消息接收方在收到消息并阅读后,调用sendMessageReceipt方法发送已读回执,调用时传入接收到的消息。

    • 如在会话界面中调用该方法并传入当前会话的最后一条消息,即表示这之前的消息本方都已读。
    • 在单聊场景中,不判断消息是否需要已读回执,即默认都需要已读回执。但是当该消息转发至群聊,群聊场景下需要判断是否需要已读回执,会读取单聊消息对象的 needMsgAck 字段,true 才发送群聊已读回执。因此在单聊场景下也建议用户按需设置该参数。

    示例代码如下:

    // 该帐号为示例,请先注册
    String account = "testAccount";
    // message为会话中已读的最后一条消息
    NIMClient.getService(MsgService.class).sendMessageReceipt(account, message);
    
  4. SDK 触发Obeserver回调函数,将已读回执(MessageReceipt)发送给消息发送方。

群聊消息已读回执

本节以发送方与接收方的消息交互为例,介绍群聊消息已读回执的实现流程。

uml diagram

前提条件

使用限制

使用群消息已读回执功能,需将群成员控制在 200 人以内。

实现流程

  1. 发送方和接收方在初始化 SDK 时,将SDKOptions#enableTeamMsgAck设置为true,启用群消息已读回执功能。

  2. 发送方在登录 IM 前,调用observeTeamMessageReceipt 注册群消息已读回执观察者,监听群消息的已读回执。

    Observer回调函数的TeamMessageReceipt接口参数说明如下:

    返回值 TeamMessageReceipt 接口 说明
    String getMsgId() 获取消息 ID
    int getAckCount() 获取已读人数
    int getUnAckCount() 获取未读人数

    示例代码:

    // 注册监听器
    NIMClient.getService(MsgServiceObserve.class).observeTeamMessageReceipt(teamMessageReceiptObserver, register);
    // 监听器的实现
    private Observer<List<TeamMessageReceipt>> teamMessageReceiptObserver = new Observer<List<TeamMessageReceipt>>() {
        @Override
        public void onEvent(List<TeamMessageReceipt> teamMessageReceipts) {
          ...
        }
    };
    
  3. 发送方调用sendMessage方法发送群消息时,需通过NIMMessage#setMsgAck方法标记该消息需要已读回执。

    示例代码如下:

    // 创建待发送消息
    IMMessage message = MessageBuilder.createTextMessage(sessionId, SessionTypeEnum.Team, "content");
    // 标记该消息需要已读回执反馈
    message.setMsgAck();
    // 发送消息
    NIMClient.getService(MsgService.class).sendMessage(message, false);
    
  4. 接收方接收到消息后,通过该消息的NIMMessage#needMsgAck属性判断该消息是否需要发送已读回执。

  5. 如需要发送已读回执,接收方可调用NIMMessage#hasSendAck方法判断是否对该消息已发送过已读回执。

  6. 接收方调用 sendTeamMessageReceipt方法发送已读回执。

    示例代码:

    NIMSDK.getTeamService().sendTeamMessageReceipt(message)
    
  7. SDK 触发Observer回调函数,将已读回执发送至消息发送方。

群聊已读回执后续操作

消息发送方获取到群聊消息已读回执后,可调用如下方法刷新消息的未读数、查询已读/未读账号列表或查询单条消息的已读/未读数。

批量刷新已读/未读数

调用refreshTeamMessageReceipt可批量刷新群聊消息已读/未读数。一般在加载消息时进行批量刷新。只有已读、未读数量有变更,才会通过观察者接口进行通知。该 API 为异步无回调接口。

单次调用,最多可传入 50 条消息体。换而言之,单次最多可刷新 50 条消息的已读/未读数。

示例代码

// messages为接收到的批量消息
NIMSDK.getTeamService().refreshTeamMessageReceipt(messages);

查询单条群组消息的已读/未读账号列表

调用fetchTeamMessageReceiptDetail方法可查询单条群组消息的已读/未读账号列表。

示例代码

//  message为待查询的消息,accountSet为账号组成的集合
NIMSDK.getTeamService().fetchTeamMessageReceiptDetail(message, accountSet).setCallback(new RequestCallback<TeamMsgAckInfo>() {
    @Override
    public void onSuccess(TeamMsgAckInfo param) {
        // 获取成功
    }

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

    @Override
    public void onException(Throwable exception) {
		// 异常
    }
});

从数据库查询单条群组消息已读/未读账号列表

调用queryTeamMessageReceiptDetailBlock方法可从本地数据库查询单条群组消息已读/未读账号列表。

调用queryTeamMessageReceiptDetailBlock方法将直接从本地数据库获取单条群组消息已读/未读账号列表,很可能是过时数据。如需获取准确数据,请调用fetchTeamMessageReceiptDetail方法。

示例代码

//  message为待查询的消息,accountSet为账号组成的集合
NIMSDK.getTeamService().queryTeamMessageReceiptDetailBlock(message, accountSet);

查询单条群组消息已读/未读账号数

通过 NIMMessage 接口的getTeamMsgAckCount方法来获取群消息已读账号数量,通过getTeamMsgUnAckCount方法来获取群消息未读账号数量。

API参考

API
说明
observeMessageReceipt 注册/注销单聊已读回执观察者,若注册则监听单聊消息已读回执
sendMessageReceipt 发送单聊消息已读回执
observeTeamMessageReceipt 注册/注销群聊已读回执观察者,若注册则监听群聊消息已读回执
sendTeamMessageReceipt 发送群聊消息已读回执
refreshTeamMessageReceipt 批量刷新群聊消息已读/未读数
fetchTeamMessageReceiptDetail 查询单条群组消息的已读/未读账号列表
queryTeamMessageReceiptDetailBlock 从本地数据库查询单条群组消息在指定用户中的已读、未读账号列表(同步接口)
此文档是否对你有帮助?
有帮助
去反馈
  • 单聊消息已读回执
  • 前提条件
  • 实现流程
  • 群聊消息已读回执
  • 前提条件
  • 使用限制
  • 实现流程
  • 群聊已读回执后续操作
  • 批量刷新已读/未读数
  • 查询单条群组消息的已读/未读账号列表
  • 从数据库查询单条群组消息已读/未读账号列表
  • 查询单条群组消息已读/未读账号数
  • API参考