跳到主要内容

获取历史消息

获取历史消息可以仅从本地数据中获取,仅从远端获取,和同时从本地与远端获取。

从 5.38.0 开始,如果返回的消息携带引用关系信息,应用可从返回的 Message 对象的 quoteInfo 属性中读取。消息本身仍保持原消息类型,例如图片回复仍是图片消息,语音回复仍是语音消息。旧版引用消息仍通过 ReferenceMessageRC:ReferenceMsg)消息体返回。

开通服务

从远端获取单群聊历史消息是指从融云服务端获取历史消息,该功能要求 App Key 已启用融云提供的单群聊消息云端存储服务。您可以在控制台 IM 服务的服务购买页面为当前使用的 App Key 开启服务。如果使用生产环境的 App Key,请注意仅 IM 旗舰版IM 尊享版可开通该服务。具体功能与费用以融云官方价格说明页面及计费说明文档为准。

提示:请注意区分历史消息记录与离线消息?。融云针对单聊、群聊、系统消息默认提供最多 7 天(可调整)的离线消息缓存服务。客户端上线时 SDK 会自动收取离线期间的消息,无需 App 层调用 API。详见管理离线消息存储配置

从本地数据库中获取消息

使用 getHistoryMessages 方法可分页查询指定会话存储在本地数据库中的历史消息,并返回消息对象列表。列表中的消息按发送时间从新到旧排列。

获取会话中所有类型的消息

Java
RongCoreClient.getInstance().getHistoryMessages(conversationType, targetId, oldestMessageId, count, callback);

count 参数表示返回列表中应包含多少消息。oldestMessageId 参数用于控制分页的边界。每次调用 getHistoryMessages 方法时,SDK 会以 oldestMessageId 参数指向的消息为界,继续在下一页返回指定数量的消息。如果需要获取会话中最新的 count 条消息,可以将 oldestMessageId 设置为 -1。

建议获取返回结果中最早一条消息的 ID,并在下一次调用时作为 oldestMessageId 传入,以便遍历整个会话的消息历史记录。

参数类型说明
conversationTypeConversationType会话类型
targetIdString会话 ID
oldestMessageIdlong最后一条消息的 ID。如需查询本地数据库中最新的消息,设置为 -1
countint每页消息的数量。
callbackIRongCoreCallback.ResultCallback<List<Message>>获取历史消息的回调,按照时间顺序从新到旧排列
Java
Conversation.ConversationType conversationType = Conversation.ConversationType.PRIVATE;
String targetId = "会话 Id";
int oldestMessageId = -1;
int count = 10;

RongCoreClient.getInstance().getHistoryMessages(conversationType, targetId, oldestMessageId, count,
new IRongCoreCallback.ResultCallback<List<Message>>() {
/**
* 成功时回调
* @param messages 获取的消息列表
*/
@Override
public void onSuccess(List<Message> messages) {
}

/**
* 错误时回调。
* @param e 错误码
*/
@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {
}
});

获取会话中指定类型的消息

Java
RongCoreClient.getInstance().getHistoryMessages(conversationType, targetId, objectName, oldestMessageId, count, callback);

count 参数表示返回列表中应包含多少消息。oldestMessageId 参数用于控制分页的边界。每次调用 getHistoryMessages 方法时,SDK 会以 oldestMessageId 参数指向的消息为界,继续在下一页返回指定数量的消息。如果需要获取会话中最新的 count 条消息,可以将 oldestMessageId 设置为 -1。objectName 参数指定需要获取的消息类型。

建议获取返回结果中最早一条消息的 ID,并在下一次调用时作为 oldestMessageId 传入,以便遍历整个会话的消息历史记录。

参数类型说明
conversationTypeConversationType会话类型。
targetIdString会话 ID。
objectNameString消息类型标识。内置消息类型的标识可参见消息类型概述
oldestMessageIdlong最后一条消息的 ID。如需查询本地数据库中最新的消息,设置为 -1
countint每页消息的数量。
callbackIRongCoreCallback.ResultCallback<List<Message>>获取历史消息的回调,按照时间顺序从新到旧排列。

通过消息 UID 获取消息

提示
  • SDK 从 5.2.5.2 版本开始支持通过 UID 批量获取消息的接口。仅在 ChannelClient 类中提供。支持的会话类型包括单聊、群聊、聊天室、超级群。
  • 如果 SDK 版本低于 5.2.5.2,可以使用 RongCoreClient 类中的 getMessageByUId 方法,该方法一次仅支持传入一个 UID。

消息的 UID 是由融云服务端生成的全局唯一 ID。消息存入本地数据库后,App 可能需要再次提取特定消息。例如,您的用户希望收藏聊天记录中的部分消息,App 可以先记录消息的 UID,在需要展示时调用 getBatchLocalMessages,传入收藏消息的 UID,从本地数据库中提取消息。

Java
ChannelClient.getInstance().getBatchLocalMessages(conversationType, targetId, channelId, messageUIDs, callback);

只要持有消息 UID(messageUIDs),并且本地数据库中已存有消息,即可以使用该方法从本地数据库提取消息。单次仅可从一个会话(targetId)或超级群频道(channelId)中提取消息。

在会话类型为超级群聊天室时,请注意以下情况:

  • 超级群会话默认只同步会话最后一条消息。如果您直接调用该方法(例如您传入了通过融云服务端回调全量消息路由获取的 UID),可能 SDK 无法在本地找到对应消息。建议先调用 getBatchRemoteUltraGroupMessages 从服务端获取消息。
  • 聊天室会话自动在用户退出清空本地消息。如果用户退出聊天室后再调用该接口,则无法取得本地消息。
参数类型说明
conversationTypeConversationType会话类型,支持单聊、群聊、聊天室、超级群。
targetIdString会话 ID
channelIdString超级群的频道 ID。非超级群会话类型时,传入空字符串 ""
messageUIDsList<String>消息的 UID,即由融云服务端生成的全局唯一 ID。必须传入有效的 UID,最多支持 20 条。
callbackIRongCoreCallback.IGetMessagesByUIDsCallback获取历史消息的回调。获取成功时会返回消息列表,和提取失败的消息的 UID 列表。
Java
Conversation.ConversationType conversationType = Conversation.ConversationType.PRIVATE;
String targetId = "会话 Id";
String sampleMessageUID = "C3GC-8VAA-LJQ4-TPPM";
List<String> messageUIDs = new ArrayList<>();
messageUIDs.add(sampleMessageUID);

ChannelClient.getInstance().getBatchLocalMessages(conversationType, targetId, null, messageUIDs,
new IRongCoreCallback.IGetMessagesByUIDsCallback() {
/**
* 成功时回调
* @param messageList 获取的消息列表
* @param mismatchList 失败的消息 UID 列表
*/
@Override
public void onSuccess(List<Message> messages, List<String> mismatchList) {

}

/**
* 错误时回调。
* @param errorCode 错误码
*/
@Override
public void onError(IRongCoreEnum.CoreErrorCode errorCode) {

}
});

按消息 UID 批量查询本地与远端消息

从 5.38.0 开始,SDK 支持通过 RongCoreClientgetMessagesByUIds 方法按消息 UId 批量查询消息。该接口会优先查询本地消息,本地未命中的消息会继续查询远端消息,适用于引用回复、收藏消息、跳转定位后补齐原消息等场景。

Java
RongCoreClient.getInstance().getMessagesByUIds(params, callback);
参数类型说明
paramsGetMessagesByUIdsParams查询参数,包含会话标识和消息 UId 列表。
callbackIRongCoreCallback.ResultCallback<List<MessageResult>>查询结果回调。每个 MessageResult 对应一条消息 UId 的查询结果。

GetMessagesByUIdsParams 中的 conversationIdentifier 表示会话标识,messageUIds 表示需要查询的消息 UId 列表。messageUIds 不能为空,列表中不能包含 null 或空字符串;如果 UId 为空,SDK 会返回 RC_INVALID_PARAMETER_MESSAGE_UID

Java
ConversationIdentifier conversationIdentifier = ConversationIdentifier.obtain(
Conversation.ConversationType.PRIVATE,
"会话 Id",
"");

List<String> messageUIds = new ArrayList<>();
messageUIds.add("C3GC-8VAA-LJQ4-TPPM");

GetMessagesByUIdsParams params = new GetMessagesByUIdsParams(
conversationIdentifier,
messageUIds);

RongCoreClient.getInstance().getMessagesByUIds(
params,
new IRongCoreCallback.ResultCallback<List<MessageResult>>() {
@Override
public void onSuccess(List<MessageResult> results) {
for (MessageResult result : results) {
Message message = result.getMessage();
IRongCoreEnum.CoreErrorCode code = result.getCode();
String messageUId = result.getMessageUId();
}
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode errorCode) {
}
});

如果需要查询超级群频道中的消息,请使用 ConversationIdentifier 传入对应的超级群频道 ID:

Java
ConversationIdentifier conversationIdentifier = ConversationIdentifier.obtainUltraGroup(
"超级群 Id",
"频道 Id");

批量获取带原始 JSON 数据的消息

提示
  • 5.40.0 版本开始,IMLib SDK 支持通过 RongCoreClient 高性能批量获取原始消息。
  • 该接口适用于批量读取消息原始 JSON 数据的场景。SDK 不会将消息内容反序列化为具体的消息类型对象,返回消息的原始 JSON 数据保存在 MessageContent.getRawJsonData() 中。
  • 该接口不支持聊天室和超级群会话类型。
  • Android 端仅支持在单进程下使用该接口。多进程环境下,消息子类无法跨进程编解码 rawJsonData,可能导致返回内容的 rawJsonData 为空。

接口

Java
RongCoreClient.getInstance().batchFetchOriginalMessage(conversationIdentifier, timestamp, count, callback);

参数说明

参数类型说明
conversationIdentifierConversationIdentifier会话标识,需要指定会话类型和会话 ID。
timestamplong分页查询的消息发送时间戳 sentTime。传 0 表示从最新消息开始获取。
countint需要获取的消息数量,取值范围为 1500
callbackIRongCoreCallback.ResultCallback<List<Message>>获取结果回调。

与普通 getHistoryMessages 系列接口不同,该接口不会将消息内容反序列化为具体的消息类型对象。如果您需要读取消息原始 JSON,可从返回的 message.getContent().getRawJsonData() 中获取。

示例代码

Java
ConversationIdentifier conversationIdentifier = ConversationIdentifier.obtain(
Conversation.ConversationType.PRIVATE,
"targetId",
"");

RongCoreClient.getInstance().batchFetchOriginalMessage(
conversationIdentifier,
0,
20,
new IRongCoreCallback.ResultCallback<List<Message>>() {
@Override
public void onSuccess(List<Message> messages) {
for (Message message : messages) {
byte[] rawJsonData = message.getContent().getRawJsonData();
String rawJsonString = new String(rawJsonData);
// 处理原始 JSON 字符串 rawJsonString
}
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode errorCode) {

}
});

获取远端历史消息

使用 getRemoteHistoryMessages 方法可直接查询指定会话存储在单群聊消息云端存储中的历史消息。

提示
  • 用户是否可以获取在加入群组之前的群聊历史消息取决于 App 在控制台的设置。您可以在需先按控制台内嵌指南嵌入到管理后台的 IM 服务功能配置页面(page_code: im_service_config)中,进入 单群聊 > 新用户获取加入群组前历史消息,启用此选项。启用后,新入群用户可以获取在他们加入群组之前发送的所有群聊消息。如不启用,新入群用户只能看到他们入群后的群聊消息。
  • 默认情况下,用户不在群组中不能获取群组中的历史消息。如果您希望用户未在指定群组中时,也可以获取群组历史消息,可以在需先按控制台内嵌指南嵌入到管理后台的 IM 服务功能配置页面(page_code: im_service_config)中,进入 单群聊 > 用户不在群组时是否可以拉取历史消息,允许不在群组的用户也可以获取该群组的的历史消息。

获取会话的远端历史消息

SDK 按照指定条件直接查询并获取单群聊消息云端存储中的满足查询条件的历史消息。查询结果与本地数据库对比,排除重复的消息后,返回消息对象列表。返回的消息列表中的消息按发送时间从新到旧排列。

因为默认该接口返回的消息会跟本地消息排重后返回,建议先使用 getHistoryMessages,在本地数据库消息全部获取完之后,再获取远端历史消息。否则可能会获取不到指定的部分或全部消息。

Java
RongCoreClient.getInstance().getRemoteHistoryMessages(conversationType, targetId, dateTime, count, callback);

count 参数表示返回列表中应包含多少消息。dateTime 参数用于控制分页的边界。每次调用 getRemoteHistoryMessages 方法时,SDK 会以 dateTime 为界,继续在下一页返回指定数量的消息。如果需要获取会话中最新的 count 条消息,可以将 dateTime 设置为 0。

建议获取返回结果中最早一条消息的 sentTime,并在下一次调用时作为 dateTime 的值传入,以便遍历整个会话的消息历史记录。

参数类型说明
conversationTypeConversationType会话类型
targetIdString会话 Id
dateTimelong时间戳,获取发送时间早于 dateTime 的历史消息。传 0 表示获取最新 count 条消息。
countint要获取的消息数量。如果 SDK < 5.4.1,范围为 [2-20];如果 SDK ≧ 5.4.1,范围为 [2-100]。
callbackIRongCoreCallback.ResultCallback<List<Message>>获取历史消息的回调,按照时间顺序从新到旧排列。
Java
Conversation.ConversationType conversationType = Conversation.ConversationType.PRIVATE;
String targetId = "会话 Id";
long dateTime = 0;
int count = 20;

RongCoreClient.getInstance().getRemoteHistoryMessages(conversationType, targetId, dateTime, count,
new IRongCoreCallback.ResultCallback<List<Message>>() {
/**
* 成功时回调
* @param messages 获取的消息列表
*/
@Override
public void onSuccess(List<Message> messages) {

}

/**
* 错误时回调。
* @param e 错误码
*/
@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {

}
});

自定义获取会话的远端历史消息

通过 RemoteHistoryMsgOption 可以自定义 getRemoteHistoryMessages 方法获取远端历史消息的行为。SDK 会按照指定条件直接查询单群聊消息云端存储中的满足查询条件的历史消息。

Java
RongCoreClient.getInstance().getRemoteHistoryMessages(conversationType, targetId, remoteHistoryMsgOption, callback);

remoteHistoryMsgOption 中包含多个配置项,其中 countdateTime 参数分别时获取历史消息的数量与分页查询时间戳。pullOrder 参数用于控制获取历史消息的时间方向,可选择获取早于或者晚于给定的 dateTime 的消息。includeLocalExistMessage 参数控制返回消息列表中是否需要包含本地数据库已存在的消息。

参数类型说明
conversationTypeConversationType会话类型
targetIdString会话 ID
remoteHistoryMsgOptionRemoteHistoryMsgOption获取远端历史消息的配置选项。
callbackIRongCoreCallback.ResultCallback<List<Message>>获取历史消息的回调。
  • RemoteHistoryMsgOption 说明

    参数说明
    dataTime时间戳,用于控制分页查询消息的边界。默认值为 0
    count要获取的消息数量。如果 SDK < 5.4.1,范围为 [2-20];如果 SDK ≧ 5.4.1,范围为 [2-100];默认值为 5
    pullOrder拉取顺序。DESCEND:降序,按消息发送时间递减的顺序,获取发送时间早于 dataTime 的消息,返回的列表中的消息按发送时间从新到旧排列。ASCEND: 升序,按消息发送时间递增的顺序,获取发送时间晚于 dataTime 的消息,返回的列表中的消息按发送时间从旧到新排列。默认值为 1
    includeLocalExistMessage是否包含本地数据库中的已有消息。true:包含,查询结果不与本地数据库排除重复,直接返回。false:不包含,查询结果先与本地数据库排除重复,只返回本地数据库中不存在的消息。默认值为 false

RemoteHistoryMsgOption 默认按消息发送时间降序查询会话中的消息,且默认会并将查询结果与本地数据库对比,排除重复的消息后,再返回消息对象列表。在 includeLocalExistMessage 设置为 false 的情况下,建议 App 层先使用 getHistoryMessages,在本地数据库消息全部获取完之后,再获取远端历史消息,否则可能会获取不到指定的部分或全部消息。

如需按消息发送时间升序查询会话中的消息,建议获取返回结果中最新一条消息的 sentTime,并在下一次调用时作为 dateTime 的值传入,以便遍历整个会话的消息历史记录。升序查询消息一般可用于跳转到会话页面指定消息位置后需要查询更新的历史消息的场景。

Java
Conversation.ConversationType conversationType= Conversation.ConversationType.PRIVATE;
String targetId="会话 Id";
RemoteHistoryMsgOption remoteHistoryMsgOption=new RemoteHistoryMsgOption();
remoteHistoryMsgOption.setDataTime(1662542712112L);//2022-09-07 17:25:12:112
remoteHistoryMsgOption.setOrder(HistoryMessageOption.PullOrder.DESCEND);
remoteHistoryMsgOption.setCount(20);

RongCoreClient.getInstance().getRemoteHistoryMessages(conversationType, targetId, remoteHistoryMsgOption,
new IRongCoreCallback.ResultCallback<List<Message>>() {
/**
* 成功时回调
* @param messages 获取的消息列表
*/
@Override
public void onSuccess(List<Message> messages) {

}

/**
* 错误时回调。
* @param e 错误码
*/
@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {

}
});

获取本地与远端历史消息

提示

该接口在 ChannelClient 类中提供。旧版 RongCoreClient 下的同名方法已过时,建议使用 ChannelClient.getInstance().getMessages(...)注意:用户是否可以获取在加入群组之前的群聊历史消息取决于 App 在控制台的设置。您可以在需先按控制台内嵌指南嵌入到管理后台的 IM 服务功能配置页面(page_code: im_service_config)中,进入 单群聊 > 新用户获取加入群组前历史消息,启用此选项。启用后,新入群用户可以获取在他们加入群组之前发送的所有群聊消息。如不启用,新入群用户只能看到他们入群后的群聊消息。

getMessages 方法与 getRemoteHistoryMessages 的区别是 getMessages 会先查询指定会话存储本地数据库的消息,当本地消息无法满足查询条件时,再查询在单群聊消息云端存储中的历史消息,以返回连续且相邻的消息对象列表。

Java
ChannelClient.getInstance().getMessages(
conversationType, targetId, channelId, historyMessageOption, callback);

通过 historyMessageOption 可以控制 getMessages 方法获取历史消息的行为。count 参数表示返回列表中应包含多少消息。dateTime 参数用于控制分页的边界。每次调用 getMessages 方法时,SDK 会以 dateTime 为界,继续在下一页返回指定数量的消息。如果需要获取会话中最新的 count 条消息,可以将 dateTime 设置为 0。pullOrder 参数用于控制获取历史消息的时间方向,可选择获取早于或者晚于给定的 dateTime 的消息。

回调 onComplete 中会返回 syncTimestamphasMoreMsg。如需继续分页拉取,建议在 hasMoreMsgtrue 时,将 syncTimestamp 作为下一次调用的 dateTime 传入,以便遍历整个会话的消息历史记录。

参数类型说明
conversationTypeConversationType会话类型
targetIdString会话 ID
channelIdString消息所属会话的业务标识。不使用频道能力时传空字符串 ""
historyMsgOptionHistoryMessageOption获取历史消息的配置选项。
callbackIRongCoreCallback.IGetMessageCallbackEx获取历史消息的回调。成功回调会返回消息列表、下次拉取的起始时间戳、服务端是否还有更多消息以及错误码。
  • HistoryMessageOption 说明

    参数说明
    dataTime时间戳,用于控制分页查询消息的边界。默认值为 0
    count要获取的消息数量。如果 SDK < 5.4.1,范围为 [2-20];如果 SDK ≧ 5.4.1,范围为 [2-100];默认值为 5
    pullOrder拉取顺序。DESCEND:降序,按消息发送时间递减的顺序,获取发送时间早于 dataTime 的消息,返回的列表中的消息按发送时间从新到旧排列。ASCEND: 升序,按消息发送时间递增的顺序,获取发送时间晚于 dataTime 的消息,返回的列表中的消息按发送时间从旧到新排列。

HistoryMessageOption 默认按消息发送时间升序查询会话中的消息。升序查询消息一般可用于跳转到会话页面指定消息位置后需要查询更新的历史消息的场景。

如需按消息发送时间降序查询会话中的消息,建议在返回结果中读取 syncTimestamp,并在下一次调用时作为 dateTime 的值传入,以便遍历整个会话的消息历史记录。

Java
Conversation.ConversationType conversationType = Conversation.ConversationType.PRIVATE;
String targetId = "会话 Id";
String channelId = ""; // 不使用频道能力时传空字符串。
HistoryMessageOption historyMessageOption = new HistoryMessageOption();
historyMessageOption.setDataTime(1662542712112L); // 2022-09-07 17:25:12:112
historyMessageOption.setOrder(HistoryMessageOption.PullOrder.ASCEND);
historyMessageOption.setCount(20);
ChannelClient.getInstance().getMessages(
conversationType,
targetId,
channelId,
historyMessageOption,
new IRongCoreCallback.IGetMessageCallbackEx() {
@Override
public void onComplete(
List<Message> messageList,
long syncTimestamp,
boolean hasMoreMsg,
IRongCoreEnum.CoreErrorCode errorCode) {
Log.e("tag", "list---" + messageList.size());
if (hasMoreMsg) {
historyMessageOption.setDataTime(syncTimestamp);
// 继续调用 getMessages 可获取下一页历史消息。
}
}

@Override
public void onFail(IRongCoreEnum.CoreErrorCode errorCode) {

}
});