历史消息
更新时间: 2024/05/24 17:41:44
云信 IM 支持在客户端本地与云端存储历史消息,供后续查询。
前提条件
已在云信控制台开通消息漫游功能。步骤如下:
-
在控制台首页应用管理中选择应用,然后单击 IM 即时通讯下的功能配置按钮进入功能配置页。
-
在顶部选择全局功能页签,开启消息漫游功能。
-
阅读并确认信息后,单击确认开启消息漫游功能。
本地历史消息
本地历史消息查询
- API 介绍
SDK 提供了一个根据锚点查询本地消息历史记录的接口,根据提供的方向 (direct),查询比 anchor(锚点消息) 更老 (QUERY_OLD) 或更新 (QUERY_NEW) 的最靠近 anchor 的 limit 条数据。调用者可使用 asc 参数指定结果排序规则,结果使用 time 作为排序字段。
- API 原型
异步版本
java/**
* 根据锚点和方向从本地消息数据库中查询消息历史。
* 根据提供的方向(direct),查询比anchor更老(QUERY_OLD)或更新(QUERY_NEW)的最靠近anchor的limit条数据。
* 调用者可使用asc参数指定结果排序规则,结果使用time作为排序字段。
* 注意:查询结果不包含锚点。
*
* @return 调用跟踪,可设置回调函数,接收查询结果
*/
public InvocationFuture<List<IMMessage>> queryMessageListEx(IMMessage anchor, QueryDirectionEnum direction, int limit, boolean asc);
同步版本
java/**
* 根据锚点和方向从本地消息数据库中查询消息历史。(同步函数)<br>
* 根据提供的方向(direct),查询比anchor更老(QUERY_OLD)或更新(QUERY_NEW)的最靠近anchor的limit条数据。<br>
* 调用者可使用asc参数指定结果排序规则,结果使用time作为排序字段。<br>
* 注意:查询结果不包含锚点。
*
* @param anchor 查询锚点
* @param direction 查询方向
* @param limit 查询结果的条数限制
* @param asc 查询结果的排序规则,如果为true,结果按照时间升序排列,如果为false,按照时间降序排列
* @return 调用跟踪,可设置回调函数,接收查询结果
*/
List<IMMessage> queryMessageListExBlock(IMMessage anchor, QueryDirectionEnum direction, int limit, boolean asc);
- 参数说明
参数 | 说明 |
---|---|
anchor | 查询锚点 |
direction | 查询方向 |
limit | 查询结果的条数限制 |
asc | 查询结果的排序规则 |
anchor
参数表示查询锚点,也就是作为查询起点的那条消息,查询结果不包含锚点。不能设置为null。
当进行首次查询时可以使用MessageBuilder.createEmptyMessage(...)
方法生成空消息作为锚点。如要查询与accid001这个账号的点对点聊天消息记录,并将2019-01-15 17:00:00 (对应的时间戳为1547542800000) 作为查询起点,则可以配置锚点:
javaIMMessage msg = MessageBuilder.createEmptyMessage("accid001", SessionTypeEnum.P2P, 1547542800000L);
direction
表示查询方向,QueryDirectionEnum.QUERY_OLD
表示比锚点更旧的消息,QueryDirectionEnum.QUERY_NEW
表示比锚点更新的消息。例如,以2019-01-15 17:00:00 (对应的时间戳为1547542800000) 为锚点:
- 如果需要查询从16:59:00到17:00:00的消息,需要设置direction为
QueryDirectionEnum.QUERY_OLD
- 如果需要查询从17:00:00到17:01:00的消息,需要设置direction为
QueryDirectionEnum.QUERY_NEW
asc
参数表示对查询结果按照时间进行排序的方式,true表示按照时间戳从小到大,false表示按照时间戳从大到小。
- 示例
java// 查询比 anchor时间更早的消息,查询20条,结果按照时间降序排列
NIMClient.getService(MsgService.class).queryMessageListEx(anchor, QueryDirectionEnum.QUERY_OLD,
20, false).setCallback(new RequestCallbackWrapper<List<IMMessage>>() {
@Override
public void onResult(int code, List<IMMessage> result, Throwable exception) {
...
}
});
按起止时间查询
- API 介绍
该接口使用方法与 queryMessageListEx
类似,增加了一个参数 toTime 作为查询方向上的的截止时间。
-
当方向为 QUERY_OLD 时,toTime 应小于 anchor.getTime();
-
当方向为 QUERY_NEW 时,toTime 应大于 anchor.getTime()。
查询结果的范围由 toTime 和 limit 共同决定,以先到为准。如果从 anchor 到 toTime 之间消息大于 limit 条,返回 limit 条记录,如果小于 limit 条,返回实际条数。
- API 原型
java/**
* 根据起始、截止时间点以及查询方向从本地消息数据库中查询消息历史。
* 根据提供的方向 (direction),以 anchor 为起始点,往前或往后查询由 anchor 到 toTime 之间靠近 anchor 的 limit 条消息。
* 查询范围由 toTime 和 limit 共同决定,以先到为准。如果到 toTime 之间消息大于 limit 条,返回 limit 条记录,如果小于 limit 条,返回实际条数。
* 查询结果排序规则:direction 为 QUERY_OLD 时 按时间降序排列,direction 为 QUERY_NEW 时按照时间升序排列。
* 注意:查询结果不包含锚点。
*
* @return 调用跟踪,可设置回调函数,接收查询结果
*/
public InvocationFuture<List<IMMessage>> queryMessageListExTime(IMMessage anchor, long toTime, QueryDirectionEnum direction, int limit);
- 参数说明
参数 | 说明 |
---|---|
anchor | 查询锚点。关于锚点消息,见上文queryMessageListEx 方法中的介绍 |
toTime | 查询截止时间,若方向为 QUERY_OLD,toTime 应小于 anchor.getTime()。 方向为 QUERY_NEW,toTime 应大于 anchor.getTime() |
direction | 查询方向 |
limit | 查询结果的条数限制 |
- 示例
java// 以P2P类型为例,testAccount为测试帐号
IMMessage msg = MessageBuilder.createEmptyMessage("testAccount", SessionTypeEnum.P2P, System.currentTimeMillis());
// 查询anchor往前10s的数据,10条
NIMClient.getService(MsgService.class).queryMessageListExTime(msg, System.currentTimeMillis() - 10000, QueryDirectionEnum.QUERY_OLD, 10).setCallback(...);
查询最近一条消息
查询同指定会话的最近一条消息
java/**
* @param account 对方的id/群id
* @param sessionType 会话类型
*/
IMMessage queryLastMessage(java.lang.String account,
SessionTypeEnum sessionType)
按消息uuid查询
- API 原型
异步版本:
java/**
* 通过消息id批量获取IMMessage
*
* @param uuids 消息id列表
* @return
*/
public InvocationFuture<List<IMMessage>> queryMessageListByUuid(List<String> uuids);
同步版本:
java/**
* 通过消息id批量获取IMMessage(同步版本)
*
* @param uuids 消息的uuid列表
* @return
*/
public List<IMMessage> queryMessageListByUuidBlock(List<String> uuids);
- 示例
java// 通过消息id批量获取IMMessage(异步版本)
List<String> uuids = new ArrayList<>();
uuids.add(message.getUuid());
NIMClient.getService(MsgService.class).queryMessageListByUuid(uuids);
// 通过消息id批量获取IMMessage(同步版本)
NIMClient.getService(MsgService.class).queryMessageListByUuidBlock(uuids);
按消息server id查询
通过 Server ID 批量获取IMMessage(同步版本) 注意:一个ServerId可能对应多条消息。
java/**
* @param serverIds 消息的Server ID列表
* 返回 ServerId在参数列表中的消息组成的列表
*/
java.util.List<IMMessage> queryMessageListByServerIdBlock(java.util.List<java.lang.String> serverIds);
按消息类型查询
- API 介绍
根据起始、截止时间点以及查询方向从本地消息数据库中查询指定消息类型的消息历史。
根据提供的方向 (direction),以 anchor 为起始点,往前或往后查询由 anchor 到 toTime 之间靠近 anchor 的 limit 条消息。
查询范围由 toTime 和 limit 共同决定,以先到为准。如果到 toTime 之间消息大于 limit 条,返回 limit 条记录,如果小于 limit 条,返回实际条数。
查询结果排序规则:如果asc为true,结果按照时间升序排列,如果为false,按照时间降序排列
注意:查询结果不包含锚点。
- API 原型
java/**
* @param types 查询的消息类型集合, 传入null表示所有消息类型
* @param anchor 查询锚点,锚点消息类型可不在查询的消息类型集合范围内
* @param toTime 查询截止时间,若方向为 QUERY_OLD,toTime 应小于 anchor.getTime()。方向为 QUERY_NEW,toTime 应大于 anchor.getTime(), 填0表示没有时间限制,以 limit限制为主
* @param direction 查询方向
* @param limit 查询结果的条数限制
* @param asc 查询结果的排序规则,如果为true,结果按照时间升序排列,如果为false,按照时间降序排列
* 返回: 调用跟踪,可设置回调函数,接收查询结果
*/
InvocationFuture<java.util.List<IMMessage>> queryMessageListByTypesV2(java.util.List<MsgTypeEnum> types,
IMMessage anchor,
long toTime,
QueryDirectionEnum direction,
int limit,
boolean asc);
按消息子类型查询
- API 介绍
根据起始时间、消息类型从本地消息数据库中查询指定消息子类型的消息历史。
以 anchor 为起始点,往前查询由 anchor 开始 的 limit 条消息。
注意:查询结果不包含锚点。
- API 原型
异步版本:
java/**
* 通过消息子类型查询本地消息记录(异步版本)
*
* @param msgTypeEnum 消息类型
* @param anchor 搜索的消息锚点
* @param limit 搜索结果的条数限制
* @param subtype 子类型
* @return InvocationFuture
*/
InvocationFuture<List<IMMessage>> queryMessageListBySubtype(MsgTypeEnum msgTypeEnum, IMMessage anchor, int limit, int subtype);
同步版本:
java/**
* 通过消息子类型查询本地消息记录(同步版本)
*
* @param msgTypeEnum 消息类型
* @param anchor 搜索的消息锚点
* @param limit 搜索结果的条数限制
* @param subtype 子类型
* @return 子类型和subtype一致的消息的列表
*/
List<IMMessage> queryMessageListBySubtypeBlock(MsgTypeEnum msgTypeEnum, IMMessage anchor, int limit, int subtype);
- 参数说明
参数 | 说明 |
---|---|
msgTypeEnum | 消息类型 |
anchor | 搜索的消息锚点 |
limit | 搜索结果的条数限制 |
subtype | 子类型 |
- 示例
javaNIMClient.getService(MsgService.class)
.queryMessageListBySubtype(getMsgTypes().get(0), msg, msgCount, subtype).setCallback(callback);
删除本地消息
删除单条消息
- API 介绍
指定一条消息进行本地删除
- API 原型
java/**
* 删除一条消息记录
*
* @param message 待删除的消息记录
* @param ignore true: 本地不记录清除操作; false: 本地记录清除操作
* 从云端拉取消息时,如果本地有删除该消息的操作记录,则该消息不会入库
* 删除标记会被清除标记覆盖
*/
void deleteChattingHistory(IMMessage message, boolean ignore);
- 参数说明
参数 | 说明 |
---|---|
message | 待删除的消息记录 |
Ignore | true: 本地不记录清除操作; false: 本地记录清除操作 从云端拉取消息时,如果本地有删除该消息的操作记录,则该消息不会入库 删除标记会被清除标记覆盖 |
- 示例
java// 删除单条消息
NIMClient.getService(MsgService.class).deleteChattingHistory(message, false);
删除多条消息
- API 介绍
指定多条消息进行本地删除
- API 原型
java/**
* 删除多条消息记录
*
* @param msgList 待删除的消息记录
* @param ignore true: 本地不记录清除操作; false: 本地记录清除操作
* 从云端拉取消息时,如果本地有删除该消息的操作记录,则该消息不会入库
* 删除标记会被清除标记覆盖
*/
void deleteChattingHistory(List<IMMessage> msgList, boolean ignore);
- 参数说明
参数 | 说明 |
---|---|
msgList | 待删除的消息记录 |
Ignore | true: 本地不记录清除操作; false: 本地记录清除操作 从云端拉取消息时,如果本地有删除该消息的操作记录,则该消息不会入库 删除标记会被清除标记覆盖 |
- 示例
java// 删除单条消息
NIMClient.getService(MsgService.class).deleteChattingHistory(msgList, false);
删除指定会话内消息
- API介绍
调用clearChattingHistory
方法将某会话的所有消息从本地数据库中移除,且可以配置是否记录此次清除操作进数据库。若记录,则当从云端把该部分消息拉取下来后,将无法同步至本地数据库中。
- 参数说明
参数 | 说明 |
---|---|
account |
聊天对象的 ID。如果是单聊,为用户的 IM 帐号(accid ),如果是群聊,则为群组 ID |
sessionType |
会话类型,包括单聊和群聊等,具体见SessionTypeEnum |
ignore |
true(默认): 本地不记录清除操作; false: 本地记录清除操作 |
- 示例
java// 本地记录清除操作
NIMClient.getService(MsgService.class).clearChattingHistory(sessionId, sessionType, false);
若要删除指定时间区段内的消息,可以使用以下接口:
java/**
* 根据时间范围删除本地历史消息(startTime, entTime), 开区间,不包括两个端点,大于startTime, 小于endTime
* @param account 对方的id/群id
* @param sessionType 会话的类型
* @param startTime 开始时间
* @param endTime 结束时间
*/
void deleteRangeHistory(java.lang.String account,
SessionTypeEnum sessionType,
long startTime,
long endTime);
删除所有消息
SDK 支持删除数据库内所有消息。
java/**
* 清空消息数据库的所有消息记录。
* 可选择是否要同时清空本地最近会话列表。
* 若最近联系人列表也被清空,会触发MsgServiceObserve.observeRecentContactDeleted(Observer, boolean)通知
* @param clearRecent 是否同时清除本地最近会话列表
*/
void clearMsgDatabase(boolean clearRecent);
云端历史消息
分页查询云端历史消息
SDK 提供了分页查询接口,查询以锚点 anchor 作为起始点(不包含锚点),根据 direction 参数,往前或往后查询由锚点到 toTime 之间的最多 limit 条消息。查询范围由 toTime 和 limit 共同决定,以先到为准。如果到 toTime 之间消息大于 limit 条,返回 limit 条记录,如果小于 limit 条,返回实际条数。当已经查询到头时,返回的结果列表的 size 可能会比 limit 小。
当进行首次查询时,锚点可以用使用 MessageBuilder#createEmptyMessage
接口生成。查询结果不包含锚点。该接口的最后一个参数可用于控制是否要将拉取到的消息记录保存到本地数据库,如果选择保存到了本地,再使用拉取本地消息记录的接口时,也能取到这些消息。
- API 原型
java/**
* 从服务器拉取消息历史记录,可以指定查询的消息类型,结果不存本地消息数据库。
* <p>
* 以锚点anchor作为起始点(不包含锚点),根据direction参数,往前或往后查询由锚点到toTime之间的最多limit条消息。<br>
* 查询范围由toTime和limit共同决定,以先到为准。如果到toTime之间消息大于limit条,返回limit条记录,如果小于limit条,返回实际条数。
* 当已经查询到头时,返回的结果列表的size可能会比limit小
*
* @param anchor 起始时间点的消息,不能为null。<br>
* 设置自定义锚点时,使用 {@link MessageBuilder#createEmptyMessage(String, SessionTypeEnum, long)} 创建一个空对象即可<br>
* @param toTime 结束时间点单位毫秒
* @param limit 本次查询的消息条数上限(最多100条)
* @param direction 查询方向,QUERY_OLD按结束时间点逆序查询,逆序排列;QUERY_NEW按起始时间点正序起查,正序排列
* @param msgTypes 消息类型,数组。消息类型仅支持 0:文本,1:图片,2:语音,3:视频,4:地理位置,5:通知,6:文件,10:提示,100:自定义,其它为非法参数
* @param persist 通过该接口获取的漫游消息记录,要不要保存到本地消息数据库。
* @param persistClear 是否保存被清除的消息到本地数据库,在persist==true时生效
* @param customFilter 过滤器回调,如果返回true则被忽略,即视为没有拉到这条消息
* @return InvocationFuture
*/
InvocationFuture<List<IMMessage>> pullMessageHistoryExType(IMMessage anchor, long toTime, int limit,
QueryDirectionEnum direction, MsgTypeEnum[] msgTypes, boolean persist,
boolean persistClear, IMMessageFilter customFilter);
- 参数说明
参数 | 说明 |
---|---|
anchor | 起始时间点的消息,不能为 null。 设置自定义锚点时,使用 MessageBuilder#createEmptyMessage 创建一个空对象即可 |
toTime | 结束时间点单位毫秒 |
limit | 本次查询的消息条数上限(最多 100 条) |
direction | 查询方向,QUERY_OLD 按结束时间点逆序查询,逆序排列; QUERY_NEW 按起始时间点正序起查,正序排列 |
persist | 通过该接口获取的漫游消息记录,要不要保存到本地消息数据库。 |
persistClear | 是否保存被清除的消息到本地数据库,在persist==true时生效 |
customFilter | 过滤器回调,如果返回true则被忽略,即视为没有拉到这条消息 |
anchor
参数表示查询锚点,也就是作为查询起点的那条消息,查询结果不包含锚点。不能设置为null。
当进行首次查询时可以使用MessageBuilder.createEmptyMessage(...)
方法生成空消息作为锚点。如要查询与accid001这个账号的点对点聊天消息记录,并将2019-01-15 17:00:00 (对应的时间戳为1547542800000) 作为查询起点,则可以配置锚点:
javaIMMessage msg = MessageBuilder.createEmptyMessage("accid001", SessionTypeEnum.P2P, 1547542800000L);
direction
表示查询方向,QueryDirectionEnum.QUERY_OLD
表示比锚点更旧的消息,QueryDirectionEnum.QUERY_NEW
表示比锚点更新的消息。例如,以2019-01-15 17:00:00 (对应的时间戳为1547542800000) 为锚点:
- 如果需要查询从16:59:00到17:00:00的消息,需要设置direction为
QueryDirectionEnum.QUERY_OLD
- 如果需要查询从17:00:00到17:01:00的消息,需要设置direction为
QueryDirectionEnum.QUERY_NEW
asc
参数表示对查询结果按照时间进行排序的方式,true表示按照时间戳从小到大,false表示按照时间戳从大到小。
- 示例
java// 服务端拉取历史消息100条
long newTime = System.currentTimeMillis();
long oldTime = newTime - 1000 * 60 * 60; // 一小时前
IMMessage anchor = MessageBuilder.createEmptyMessage("testAccount", SessionTypeEnum.P2P, newTime);
NIMClient.getService(MsgService.class).pullMessageHistoryEx(anchor, oldTime, 100, QueryDirectionEnum.QUERY_OLD, false, false, message -> false) .setCallback(callback);
此外,还提供如下简单接口:
从服务器拉取消息历史记录。该接口查询方向为从后往前。以锚点anchor作为起始点(不包含锚点),往前查询最多limit条消息。 当已经查询到头时,返回的结果列表的size可能会比limit小。
java/**
* @param anchor 查询锚点
* @param limit 本次查询的消息条数上限(最多100条)
* @param persist 通过该接口获取的历史消息记录,是否保存到本地消息数据库。
* @param persistClear 是否保存清除记录之前的消息到本地数据库,在persist==true时生效
*/
InvocationFuture<java.util.List<IMMessage>> pullMessageHistory(IMMessage anchor,
int limit,
boolean persist,
boolean persistClear);
调用pullMessageHistory
从服务端拉取历史消息时,如果将persist
参数设置为false
,只能获取服务端的数据,不会使用本地数据库中更新过的数据,因此可能导致消息状态变更,触发observeMsgStatus
消息状态变化观察者的回调。如需避免这种情况,请将persist
参数设置为true
。
按消息类型查询云端历史消息
从服务器拉取历史消息时,可以指定查询的消息类型。
- API 原型
java/**
*
* @param anchor 起始时间点的消息,不能为null。
* @param toTime 结束时间点,单位毫秒。
* @param limit 本次查询的消息条数上限(最多100条)
* @param direction 查询方向,QUERY_OLD按结束时间点逆序查询,逆序排列;QUERY_NEW按起始时间点正序起查,正序排列
* @param msgTypes 消息类型,数组。消息类型仅支持 0:文本,1:图片,2:语音,3:视频,4:地理位置,5:通知,6:文件,10:提示,100:自定义,其它为非法参数
* @param persist 通过该接口获取的历史消息记录,要不要保存到本地消息数据库。
* @param persistClear 是否保存被清除的消息到本地数据库
* @return InvocationFuture
*/
InvocationFuture<java.util.List<IMMessage>> pullMessageHistoryExType(IMMessage anchor,
long toTime,
int limit,
QueryDirectionEnum direction,
MsgTypeEnum[] msgTypes,
boolean persist,
boolean persistClear);
查询云端 Thread 历史消息
支持通过 Thread 根消息,分页查询服务端 Thread 历史消息(单聊、群、超大群)。
- API原型
java/**
* 分页查询服务端 Thread 历史消息(支持单聊、群、超大群)。
*
* @param threadMessageKey 要查询的 Thread 根消息
* @param option 查询选项
* @return InvocationFuture<ThreadTalkHistory> 可设置回调函数:查询成功后返回 Thread 历史消息;查询失败后返回具体错误码。
*/
InvocationFuture<ThreadTalkHistory> queryThreadTalkHistory(MessageKey threadMessageKey, QueryThreadTalkHistoryOption option);
-
参数说明
参数 类型 说明 threadMessageKey
MessageKey
Thread 根消息,该方法通过该根消息查询 Thread 消息。 option
QueryThreadTalkHistoryOption
查询选项,包含起始、结束时间、查询方向(结果排序方式)等。 QueryThreadTalkHistoryOption
说明:由于安卓平台特性,您需要通过
set
和get
方法设置和获取以下参数。参数名 类型 默认值 描 述 fromTime
long 0,不限制 查询的起始时间。 fromTime
必须小于或等于toTime
。查询结果是否包含起始时间点上的消息,取决于查询方向direction
。- 消息从新往旧查询(QUERY_OLD):不包括
- 消息从旧往新查询(QUERY_NEW):包括
toTime
long 0,不限制 查询的结束时间。 fromTime
必须小于或等于toTime
。查询结果包括结束时间点上的消息。excludeMessageServerId
long 0,不设置 要排除的服务端消息 ID( serverID
)。同时对应的消息可作为查询锚点。
若该字段有效,该服务器 ID 对应的消息不会出现在查询结果中。满足下面条件时该字段有效:- 对应的消息存在。
direction
为QUERY_OLD
时,消息时间必须和toTime
相等。direction
为QUERY_NEW
时,消息时间必须和fromTime
相等。limit
int 0,不限制 查询消息条数上限。如果实际结果超出 limit
,只返回limit
数量的消息。direction
QueryDirectionEnum
null,从新往旧查询(QUERY_OLD) 查询方向,同时也是查询消息结果的排序顺序。
从新往旧查询时,查询从toTime
开始,结果中的消息按照时间从大到小排序。从旧往新查询时,查询从fromTime
开始,结果中的消息按照时间从小到大排序。persist
boolean false 查询结果是否同步到本地数据库。
删除云端历史消息
删除单会话云端历史消息
- API原型
java/**
* 清空历史消息
*
* @param sessionId 用户帐号
* @param sessionType 聊天类型
* @param sync 是否同步给其他端
* @param ext 扩展字段
*/
void clearServerHistory(String sessionId, SessionTypeEnum sessionType, boolean sync, String ext);
- 参数说明
参数 | 说明 |
---|---|
sessionId | 用户帐号 |
sessionType | 聊天类型 |
sync | 是否同步给其他端 |
ext | 扩展字段 |
- 示例
javaNIMClient.getService(MsgService.class).clearServerHistory(sessionId, sessionType, true, "");
开通单向删除消息功能
使用单向删除历史消息功能前,需在云信控制台进行开启单向删除消息配置项,步骤如下:
-
在控制台首页应用管理中选择应用,然后单击 IM 即时通讯下的功能配置按钮进入功能配置页。
-
在顶部选择全局功能页签,开启单向删除消息。
-
阅读并确认信息后,单击确认开启单向删除消息功能。
单向删除单条云端历史消息
用户单向删除一条消息成功后,该账号下不再能从服务端拉取到该条消息。而且,本端登录此账号的其他端都会删除本地的该消息记录。其他账号不受到该操作影响。删除成功后,会触发 MsgServiceObserve#observeDeleteMsgSelf
回调。
- API原型
java/**
* 删除本地某条消息,并同时单向删除服务端历史、漫游
* @param msg 被单向删除的消息
* @param ext 扩展字段
*/
InvocationFuture<Long> deleteMsgSelf(IMMessage msg, String ext);
- 参数说明
参数 | 说明 |
---|---|
msg | 要被单向删除的消息 |
ext | 扩展字段,选填 |
- 示例
javaNIMClient.getService(MsgService.class).deleteMsgSelf(selectedItem, "").setCallback(new RequestCallback<Long>() {
@Override
public void onSuccess(Long param) {
deleteItem(selectedItem, true);
}
@Override
public void onFailed(int code) {
ToastHelper.showToast(NimUIKit.getContext(), container.activity.getString(R.string.delete_msg_self_failed) + ", code=" + code);
}
@Override
public void onException(Throwable exception) {
NimLog.i("delete msg self", exception.getMessage());
}
});
单向删除多条云端历史消息
- API 原型
java/**
* 单向删除多条消息,需要来自同一会话
*
* @param msgList 被单向删除的消息列表
* @param ext 扩展字段
*/
InvocationFuture<Long> deleteMsgSelf(List<IMMessage> msgList, String ext);
- 参数说明
参数 | 说明 |
---|---|
msgList | 被单向删除的消息列表 |
ext | 扩展字段 |
- 示例
javaNIMClient.getService(MsgService.class).deleteMsgSelf(checked, "").setCallback(new RequestCallback<Long>() {
@Override
public void onSuccess(Long param) {
ToastHelper.showToast(MsgSelectActivity.this, "单向删除成功 " + param);
mMsgAdapter.deleteItems(checked, true);
finish();
}
@Override
public void onFailed(int code) {
ToastHelper.showToast(MsgSelectActivity.this, "单向删除失败 code=" + code);
}
@Override
public void onException(Throwable exception) {
ToastHelper.showToast(MsgSelectActivity.this, "单向删除错误 msg=" + exception.getMessage());
exception.printStackTrace();
}
});
消息检索
SDK当前支持关键字检索,可以通过 lucene插件 进行检索,也可以通过 SDK 本身自带的检索功能。
本地消息检索
单会话检索
- API 介绍
SDK 提供了按照关键字搜索聊天记录的功能,可以对指定的聊天对象,输入关键字进行消息内容搜索。查询方向为从后往前。以锚点 anchor 作为起始点开始查询,返回最多 limit 条匹配 keyword 的记录。该接口目前仅搜索文本类型的消息,匹配规则为文本内容包含 keyword,目前仅支持精确匹配,不支持模糊匹配和拼音匹配。
- API 原型
java/**
* 从本地消息数据库搜索消息历史。查询范围由anchor的sessionId和sessionType决定。
* 按查询方向返回最多limit条匹配key的记录。
* 该接口目前仅搜索文本类型的消息,匹配规则为文本内容包含keyword,仅支持精确匹配,不支持模糊匹配和拼音匹配。
* 注意:搜索结果不包含anchor
* @return InvocationFuture
*/
InvocationFuture<java.util.List<IMMessage>> searchMessageHistory(java.lang.String keyword, java.util.List<java.lang.String> fromAccounts, IMMessage anchor, QueryDirectionEnum direction, int limit);
- 参数说明
参数 | 说明 |
---|---|
keyword | 文本消息的搜索关键字 |
fromAccounts | 消息说话者帐号列表 |
anchor | 搜索的消息锚点 |
direction | 查询方向 |
limit | 搜索结果的条数限制 |
- 示例
java// 搜索『关键字』20条
NIMClient.getService(MsgService.class).searchMessageHistory("关键字", fromAccounts, anchor, direction,20)
.setCallback(new RequestCallbackWrapper<List<IMMessage>>(){ ... });
单会话检索(新)
- API 介绍
SDK 提供了搜索单会话聊天记录的功能,搜索将返回:时间在 (startTime,endTime) 之间,消息类型为指定类型,且匹配搜索内容或消息发起者列表的一定数量的消息。
- API 原型
java /**
* 从本地消息数据库搜索消息历史。
* 搜索将返回:时间在 (startTime,endTime) 之间,消息类型为指定类型,且匹配搜索内容或消息发起者列表的一定数量的消息。
*
* @param sessionType 会话类型
* @param sessionId 聊天对象ID
* @param option 搜索选项
* @return InvocationFuture
*/
InvocationFuture<List<IMMessage>> searchMessage(SessionTypeEnum sessionType, String sessionId, MsgSearchOption option);
其中 option 为搜索选项,具体选项如下:
参数 | 说明 |
---|---|
startTime | 起始时间,默认为0 |
endTime | 结束时间。默认为0,表示最大时间戳。若自行设置,要保证endTime晚于startTime。 |
limit | 检索条数,默认100条,设置为0表示无条数限制 |
order | 查询方向,默认为SearchOrderEnum.DESC表示从新消息往旧消息查,设置为SearchOrderEnum.ASC表示从旧消息往新消息查。无论查询方向如何,查询结果都按照旧消息到新消息的顺序排列。 |
messageTypes | 消息类型组合,默认只搜索文本类型, 只有在 allMessageTypes 为 false 时有效 |
messageSubTypes | 查询的消息子类型组合 |
allMessageTypes | 搜索全部消息类型。默认为 false,当设置为 true 时,忽略 messageType,同时返回所有的消息类型消息。 |
searchContent | 检索文本,如果需要搜索的消息类型为文本,会进行内容的匹配 |
fromIds | 消息发起者列表 |
enableContentTransfer | 将搜索文本中的正则特殊字符转义,默认 true |
- 示例
java// 搜索『关键字』最新的100条消息
MsgSearchOption option = new MsgSearchOption();
option.setSearchContent("关键字");
option.setLimit(100);
NIMClient.getService(MsgService.class).searchMessage(SessionTypeEnum.P2P,"testAccount",option)
.setCallback(new RequestCallbackWrapper<List<IMMessage>>(){ ... });
全局检索
此外,SDK 还提供了按照关键字全局搜索聊天记录的接口:MsgService#searchAllMessageHistory,用法与上述类似。目前暂不提供索引方式的全文检索功能,该全局搜索接口需要开发者评估大数据情况下的性能开销。
根据时间点搜索消息历史。该接口查询方向以某个时间点为基准从后往前,返回最多 limit 条匹配 key 的记录。该接口目前仅搜索文本类型的消息,匹配规则为文本内容包含 keyword,仅支持精确匹配,不支持模糊匹配和拼音匹配。
- API 原型
java/**
* 从本地消息数据库搜索消息历史。
* 该接口查询方向以某个时间点为基准从后往前,返回最多limit条匹配key的记录。
* 该接口目前仅搜索文本类型的消息,匹配规则为文本内容包含keyword,仅支持精确匹配,不支持模糊匹配和拼音匹配。
* @return InvocationFuture
*/
public InvocationFuture<List<IMMessage>> searchAllMessageHistory(String keyword, List<String> fromAccounts, long time, int limit);
- 参数说明
参数 | 说明 |
---|---|
keyword | 文本消息的搜索关键字 |
fromAccounts | 消息说话者帐号列表。 |
time | 以该时间点为基准从后往前查 |
limit | 搜索结果的条数限制 |
- 示例
javaNIMClient.getService(MsgService.class).searchAllMessageHistory(keyword, fromAccounts, time, limit)
.setCallback(new RequestCallbackWrapper<List<IMMessage>>(){ ... });
全局检索(新)
- API 介绍
SDK 提供了搜索全局聊天记录的功能,搜索将返回:时间在 (startTime,endTime) 之间,消息类型为指定类型,且匹配搜索内容或消息发起者列表的一定数量的消息。
- API 原型
java /**
* 从本地消息数据库全局搜索消息历史。
* 搜索将返回:时间在 (startTime,endTime) 之间,消息类型为指定类型,且匹配搜索内容或消息发起者列表的一定数量的消息。
*
* @param option 搜索选项
* @return InvocationFuture
*/
InvocationFuture<List<IMMessage>> searchAllMessage(MsgSearchOption option);
其中 option 为搜索选项,具体选项如下:
参数 | 说明 |
---|---|
startTime | 起始时间,默认为0 |
endTime | 结束时间。默认为0,表示最大时间戳。若自行设置,要保证endTime晚于startTime。 |
limit | 检索条数,默认100条,设置为0表示无条数限制 |
order | 查询方向,默认为SearchOrderEnum.DESC表示从新消息往旧消息查,设置为SearchOrderEnum.ASC表示从旧消息往新消息查。无论查询方向如何,查询结果都按照旧消息到新消息的顺序排列。 |
messageTypes | 消息类型组合,默认只搜索文本类型, 只有在 allMessageTypes 为 false 时有效 |
messageSubTypes | 查询的消息子类型组合 |
allMessageTypes | 搜索全部消息类型。默认为 false,当设置为 true 时,忽略 messageType,同时返回所有的消息类型消息。 |
searchContent | 检索文本,如果需要搜索的消息类型为文本,会进行内容的匹配 |
fromIds | 消息发起者列表 |
enableContentTransfer | 将搜索文本中的正则特殊字符转义,默认 true |
- 示例
java// 搜索『关键字』最新的100条消息
MsgSearchOption option = new MsgSearchOption();
option.setSearchContent("关键字");
option.setLimit(100);
NIMClient.getService(MsgService.class).searchAllMessage(option)
.setCallback(new RequestCallbackWrapper<List<IMMessage>>(){ ... });
查询命中消息数
通过以下接口可以返回命中关键字的消息数:
java/*
* @param query 待检索的字符串
* @param limit 最多返回多少条记录
*/
// 异步
InvocationFuture<java.util.List<MsgIndexRecord>> searchAllSession(java.lang.String query, int limit);
// 同步
java.util.List<MsgIndexRecord> searchAllSessionBlock(java.lang.String query, int limit);
若要返回所有的命中消息记录,可以使用如下接口:
java/**
* 检索指定的会话,返回该会话中与检索串匹配的所有消息记录。
*/
// 异步
InvocationFuture<java.util.List<MsgIndexRecord>> searchSession(java.lang.String query, SessionTypeEnum sessionType, java.lang.String sessionId);
// 同步
java.util.List<MsgIndexRecord> searchSessionBlock(java.lang.String query, SessionTypeEnum sessionType, java.lang.String sessionId);
云端消息检索
如果您需要使用该功能,请先开通 IM 套餐包。
开启全文云端消息检索功能
使用全文云端消息检索功能前,需在云信控制台进行开启,步骤如下:
-
在控制台首页应用管理中选择应用,然后单击 IM 即时通讯下的功能配置按钮进入功能配置页。
-
在顶部选择全局功能页签,开启全文云端消息检索功能。
-
阅读并确认信息后,单击确认开启全文云端消息检索功能。
单聊云端消息检索
- API原型
java/**
* 云端聊天记录关键词查询
*
* @param otherAccid 对方的account
* @param fromTime 起始时间点单位毫秒
* @param endTime 结束时间点单位毫秒
* @param keyword 搜索的关键词
* @param limit 本次查询的消息条数上限(最多100条)
* @param reverse 可选参数,不传默认false,true是表示反向查询(按时间正序起查,正序排列),默认false表示按时间逆序起查,逆序排列
*/
InvocationFuture<ArrayList<IMMessage>> searchRoamingMsg(String otherAccid, long fromTime, long endTime, String keyword, int limit, boolean reverse);
- 参数说明
参数 | 说明 |
---|---|
otherAccid | 对方的account |
fromTime | 起始时间点单位毫秒 |
endTime | 结束时间点单位毫秒 |
keyword | 搜索的关键词 |
limit | 本次查询的消息条数上限(最多100条) |
reverse | 可选参数,不传默认false,true是表示反向查询(按时间正序起查,正序排列),默认false表示按时间逆序起查,逆序排列 |
- 示例
javaNIMClient.getService(MsgService.class).searchRoamingMsg(
accidEdit.getText().toString(),
startTime,
endTime,
keywordEdit.getText().toString(),
queryAmount,
true).setCallback(new RequestCallback<ArrayList<IMMessage>>() {
@Override
public void onSuccess(ArrayList<IMMessage> param) {
StringBuilder roamingmsg = new StringBuilder();
for (IMMessage RoamingMsg:param){
roamingmsg.append("sessionid:"+ RoamingMsg.getSessionId());
roamingmsg.append(" ,消息内容:" + RoamingMsg.getContent());
roamingmsg.append(" ,发生时间:" + RoamingMsg.getTime());
roamingmsg.append(" ,会话类型:" + RoamingMsg.getSessionType());
}
roamingMsg.setText(roamingmsg.toString());
}
@Override
public void onFailed(int code) {
Toast.makeText(SessionActivity2.this, "云端聊天记录关键词查询失败, code=" + code, Toast.LENGTH_SHORT).show();
}
@Override
public void onException(Throwable exception) {
Toast.makeText(SessionActivity2.this, "云端聊天记录关键词查询出现异常, msg=" + exception.getMessage(), Toast.LENGTH_SHORT).show();
}
});
群聊云端消息检索
java/**
* 群组会话云端历史消息关键词查询
* @param tid 群id
* @param fromTime 起始时间点 单位毫秒
* @param endTime 结束时间点 单位毫秒
* @param keyword 查询关键词
* @param limit 本次查询的消息条数上限(最多100条)
* @param reverse true是表示反向查询(按时间正序起查,正序排列),默认false表示按时间逆序起查,逆序排列
*/
InvocationFuture<java.util.List<IMMessage>> searchTeamMsgByKeyword(long tid,
long fromTime,
long endTime,
java.lang.String keyword,
int limit,
boolean reverse);
全文云端消息检索(按会话聚合排列)
- API原型
java/**
* 云端历史消息全文检索
*
* @param config 配置
*/
InvocationFuture<List<IMMessage>> pullMessageHistory(MsgFullKeywordSearchConfig config);
- 参数说明
MsgFullKeywordSearchConfig变量表
参数 | 说明 |
---|---|
keyword | 关键词 类型:String |
fromTime | 起始时间 类型:long |
toTime | 终止时间 类型:long |
sessionLimit | 会话数量上限 类型:int |
msgLimit | 会话数量下限 类型:int |
asc | 消息排序规则,默认false 类型:boolean |
p2pList | P2P范围,要查询的会话范围是此参数与{@link MsgFullKeywordSearchConfig#teamList} 的并集 类型:List |
teamList | 群范围,如果只查询指定群中的消息,则输入这些群的ID 类型:List |
- 示例
javaMsgFullKeywordSearchConfig config = new MsgFullKeywordSearchConfig(keyword, startTime, endTime);
config.setMsgLimit(msgAmountLimit);
config.setSessionLimit(contactAmountLimit);
config.setP2pList(p2pIdList);
config.setTeamList(teamIdList);
config.setAsc(binding.cbSortTypeAsc.isChecked());
NIMClient.getService(MsgService.class).pullMessageHistory(config).setCallback(callback)
全文云端消息检索(按消息时间排列)
- API原型
java/**
* 云端历史消息全文检索(按时间排序,不按会话分组)
*
* @param config 检索配置
*/
InvocationFuture<List<IMMessage>> pullMessageHistoryOrderByTime(MsgTimingFullKeywordSearchConfig config);
- 参数说明
MsgTimingFullKeywordSearchConfig变量表
参数 | 说明 |
---|---|
keyword | 关键词 类型:String |
fromTime | 起始时间 类型:long |
toTime | 终止时间 类型:long |
msgLimit | 会话数量下限 类型:int,默认20,最大100 |
order | 消息排序规则,默认为SearchOrderEnum.DESC表示从新消息往旧消息查,设置为SearchOrderEnum.ASC表示从旧消息往新消息查 |
p2pList | P2P范围,要查询的会话范围是此参数与{@link MsgTimingFullKeywordSearchConfig#teamList} 的并集 类型:List |
teamList | 群范围,如果只查询指定群中的消息,则输入这些群的ID 类型:List |
senderList | 消息发送者账户列表 类型:List |
msgTypeList | 消息类型列表 类型:List |
msgSubtypeList | 消息子类型列表 类型:List |
lucene插件检索
云信 SDK v2.7.0 加入基于 Lucene 的全文检索插件,支持在客户端本地进行聊天消息的全文检索。目前开放的查询接口适用于两类需求:
- 需求1:
检索所有会话,返回所有匹配关键字的会话、每个会话匹配关键字的消息条数。如果会话只有一条消息匹配,那么直接返回该消息内容,返回的会话数量可以指定,也可以一次性列出所有会话。会话间的排序规则,按照每个会话最近一条匹配消息的时间倒序排列。需要支持多个关键字查询,采用空格隔开,关键字之间是 AND 关系。
- 需求2:
检索单个会话,返回所有匹配关键字的消息,并高亮显示被击中的关键字,可以跳转到该消息的上下文。
云信 SDK 目前主要针对上述两种需求提供查询服务,只要集成了全文检索插件,SDK 会自动同步所有聊天记录到全文检索索引中。 在 v2.8.0 版本我们已经对依赖的 Lucene 源码做了大幅度的精简,约 1M+ 的大小,对于大的工程,仍然可能造成方法数 65535 的限制,此时可能需要 Multi dex 的支持。
插件集成
参见SDK集成。
接口说明
全文检索接口为:LuceneService ,具体 API 如下(下面只列出异步版本,同步版本 API 也提供,详见客户端API文档 )。针对需求2,强烈建议您使用分页查询接口。
java/**
* 检索所有会话,返回每个会话与检索串匹配的消息数及最近一条匹配的消息记录。(异步函数)
*
* @param query 待检索的字符串
* @param limit 最多返回多少条记录
* @return InvocationFuture 可以设置回调函数,回调时返回聊天消息全文检索结果集
*/
public InvocationFuture<List<MsgIndexRecord>> searchAllSession(String query, int limit);
/**
* 检索指定的会话,返回该会话中与检索串匹配的所有消息记录。(异步函数)
*
* @param query 待检索的字符串
* @param sessionType 待检索的会话类型(个人/群组)
* @param sessionId 待检索的会话ID
* @return 聊天消息全文检索结果集
*/
public InvocationFuture<List<MsgIndexRecord>> searchSession(String query, SessionTypeEnum sessionType, String sessionId);
/**
* 指定会话关键字查询(分页返回匹配记录)(异步)
*
* @param query 待检索的字符串
* @param sessionType 待检索的会话类型(个人/群组)
* @param sessionId 待检索的会话ID
* @param pageIndex 页码(从第一页开始)
* @param pageSize 分页大小
* @return InvocationFuture 可以设置回调函数,回调时返回聊天消息全文检索结果集
*/
public InvocationFuture<List<MsgIndexRecord>> searchSessionPage(String query, SessionTypeEnum sessionType, String sessionId, int pageIndex, int pageSize);
/**
* 指定会话关键字查询(分页查询:根据锚点,返回下一页匹配记录)(异步)
*
* @param query 待检索的字符串
* @param sessionType 待检索的会话类型(个人/群组)
* @param sessionId 待检索的会话ID
* @param anchor 首页传null,下一页传上一页的最后一条记录
* @param pageSize 分页大小
* @return InvocationFuture 可以设置回调函数,回调时返回聊天消息全文检索结果集
*/
public InvocationFuture<List<MsgIndexRecord>> searchSessionNextPage(String query, SessionTypeEnum sessionType, String sessionId, MsgIndexRecord anchor, int pageSize);
/**
* 指定会话关键字查询匹配记录总数(同步)
*
* @param query 待检索的字符串
* @param sessionType 待检索的会话类型(个人/群组)
* @param sessionId 待检索的会话ID
* @return 匹配的记录总数
*/
public int searchSessionMatchCount(String query, SessionTypeEnum sessionType, String sessionId);
/**
* 指定会话关键字查询匹配记录总页数(同步)
*
* @param query 待检索的字符串
* @param sessionType 待检索的会话类型(个人/群组)
* @param sessionId 待检索的会话ID
* @param pageSize 分页每页记录数
* @return 匹配的记录总页数
*/
public int searchSessionPageCount(String query, SessionTypeEnum sessionType, String sessionId, int pageSize);
/**
* 获取所有缓存数据的大小
* @return 缓存数据字节数
*/
public long getCacheSize();
/**
* 删除所有缓存数据
*/
public void clearCache();
动态查询历史消息
为了获取完整的历史消息记录,您可以使用全云端方案,即用户每次进入时都通过查询云端历史记录并将查到的消息同步至本地。但是在会话多、消息多的场景下,使用全云端方案,会导致耗时长,耗能大等问题。
为解决上述问题,云信 IM 提供本地+云端智能调度方案,通过调用完整的内部逻辑保证历史消息的连续性和完整性。您仅需要选择开始或结束时间戳以及对应的消息条数即可按需获取历史消息。
开启动态查询历史消息功能
请先在云信控制台开通动态查询历史消息功能,否则该接口只会从本地数据库获取消息。
-
在控制台首页应用管理中选择应用,然后单击 IM 即时通讯下的功能配置按钮进入功能配置页。
-
在顶部选择全局功能页签,开启动态查询历史消息功能。
-
阅读并确认信息后,单击确认开启动态查询历史消息功能。
接口说明
通过调用 getMessagesDynamically
方法动态查询连续的历史消息。
该接口为完整独立的历史消息查询接口,与其他历史消息查询接口互不影响。
参数说明:
参数 | 说明 |
---|---|
sessionId | 会话 ID |
sessionType | 会话类型,具体请参见SessionTypeEnum |
fromTime | 开始时间 |
toTime | 结束时间,大于开始时间,0 表示当前时间 |
limit | 查询的历史消息数量,取值范围为 [0,100],若传入 0,则视为查询 100 条 |
anchorServerId | 查询起始的服务端消息 ID,查询结果不包括这条消息 |
anchorClientId | 查询起始的客户端消息 ID,查询结果不包括这条消息 |
direction | 查询方向,GetMessageDirectionEnum ,默认FORWARD ,即从新往旧查询 |
回调结果说明:
结果 | 说明 |
---|---|
isReliable() | 结果是否可信(连续)。未开启功能,云端请求失败等情况下,此字段为 false,代表消息不一定连续;为 true,代表查询到的消息连续 |
getMessages() | 查询到的消息列表,排序与 direction 相同 |
若只需要查询最新的 100 条历史消息,则只需传入 sessionId
和 sessionType
,其他都可使用默认值。
示例代码如下:
//查询最新的 100 条历史消息
GetMessagesDynamicallyParam param = new GetMessagesDynamicallyParam(sessionId, sessionType);
param.setLimit(100);
NIMClient.getService(MsgService.class).getMessagesDynamically(param).setCallback(new RequestCallback<GetMessagesDynamicallyResult>() {
@Override
public void onSuccess(GetMessagesDynamicallyResult result) {
if (result == null) {
// 异常情况
return;
}
if (result.isReliable()) {
// 查到的消息是可信(连续)的,消息列表的顺序默认为从新往旧
} else {
// 查到的消息是不可信(不连续)的,消息列表的顺序默认为从新往旧
}
}
@Override
public void onFailed(int code) {
// 失败
}
@Override
public void onException(Throwable exception) {
// 异常
}
});
若需要查询某条消息(message)之前的 100 条历史消息,除了传入 sessionId
和 sessionType
外,还需要传入该条消息的时间戳(toTime
)、服务端 ID(anchorServerId
)、客户端 ID 信息(anchorClientId
)。
示例代码如下:
GetMessagesDynamicallyParam param = new GetMessagesDynamicallyParam(message.getSessionId(), message.getSessionType());
param.setLimit(100);
param.setToTime(message.getTime());
param.setAnchorServerId(message.getServerId());
param.setAnchorClientId(message.getUuid());
NIMClient.getService(MsgService.class).getMessagesDynamically(param).setCallback(new RequestCallback<GetMessagesDynamicallyResult>() {
@Override
public void onSuccess(GetMessagesDynamicallyResult result) {
if (result == null) {
// 异常情况
return;
}
if (result.isReliable()) {
// 查到的消息是可信(连续)的,消息列表的顺序默认为从新往旧
} else {
// 查到的消息是不可信(不连续)的,消息列表的顺序默认为从新往旧
}
}
@Override
public void onFailed(int code) {
// 失败
}
@Override
public void onException(Throwable exception) {
// 异常
}
});
若需要查询某条消息(message)之后的 100 条历史消息,除了传入 sessionId
和 sessionType
外,还需要将查询方向(direction
)设置为 BACKWARD
,传入该条消息的时间戳(fromTime
)、服务端 ID(anchorServerId
)、客户端 ID 信息(anchorClientId
)。
示例代码如下:
GetMessagesDynamicallyParam param = new GetMessagesDynamicallyParam(message.getSessionId(), message.getSessionType());
param.setLimit(100);
param.setDirection(GetMessageDirectionEnum.FORWARD);
param.setFromTime(message.getTime());
param.setAnchorServerId(message.getServerId());
param.setAnchorClientId(message.getUuid());
NIMClient.getService(MsgService.class).getMessagesDynamically(param).setCallback(new RequestCallback<GetMessagesDynamicallyResult>() {
@Override
public void onSuccess(GetMessagesDynamicallyResult result) {
if (result == null) {
// 异常情况
return;
}
if (result.isReliable()) {
// 查到的消息是可信(连续)的,消息列表的顺序为从旧往新(与查询时设置的direction一致)
} else {
// 查到的消息是不可信(不连续)的,消息列表的顺序为从旧往新(与查询时设置的direction一致)
}
}
@Override
public void onFailed(int code) {
// 失败
}
@Override
public void onException(Throwable exception) {
// 异常
}
});