聊天扩展

消息回复

没有回复对象的消息被称为thread消息;有回复对象的消息被称为回复消息。

thread消息可以被多条消息回复,这些消息都是回复消息;回复消息的回复对象可以是thread消息,也可以是回复消息。如果一条回复消息的回复对象是thread消息,则该回复消息对应的thread消息就是其回复对象;否则该回复消息对应的thread消息和被回复消息对应的thread消息相同。

所有对应相同thread消息的回复消息组成一个thread会话。

消息回复

/**
 * 回复消息。<br>
 * 如果需要更新发送进度,请调用{@link MsgServiceObserve#observeMsgStatus(com.netease.nimlib.sdk.Observer, boolean)}
 *
 * @param msg    带发送的消息体,由{@link MessageBuilder}构造
 * @param replyMsg 被回复的消息
 * @param resend 如果是发送失败后重发,标记为true,否则填false
 * @return InvocationFuture 可以设置回调函数。消息发送完成后才会调用,如果出错,会有具体的错误代码。
 */
InvocationFuture<Void> replyMessage(IMMessage msg, IMMessage replyMsg, boolean resend);
参数 说明
msg 带发送的消息体,由{@link MessageBuilder}构造
replyMsg 被回复的消息
resend 如果是发送失败后重发,标记为true,否则填false
NIMClient.getService(MsgService.class).replyMessage(message, replymessage.get(0), false).setCallback(new RequestCallback<Void>() {
                @Override
                public void onSuccess(Void param) {
                    //回复消息成功
                }

                @Override
                public void onFailed(int code) {
                  //回复消息失败,code为错误码
                }

                @Override
                public void onException(Throwable exception) {
                  //回复消息产生异常
                }
            })

注意:在超大群中,回复消息应使用 SuperTeamService

查询thread聊天云端历史

/**
 * 查询thread聊天云端历史(支持p2p、群、超大群)
 *
 * @param anchor 查找锚点,查找对象为此消息所在的thread中的消息
 * @param fromTime 起始时间
 * @param toTime 终止时间
 * @param limit 条数限制
 * @param direction 方向
 * @param persist 是否持久化
 * @return InvocationFuture
 */
InvocationFuture<ThreadTalkHistory> queryThreadTalkHistory(IMMessage anchor, long fromTime, long toTime, int limit, QueryDirectionEnum direction, boolean persist);
参数 说明
anchor 查找锚点,查找对象为此消息所在的thread中的消息
fromTime 起始时间
toTime 终止时间
limit 条数限制
direction 方向
persist 是否持久化
NIMClient.getService(MsgService.class).queryThreadTalkHistory(replymessage.get(0), aTime, tTime, msgCount, direction, true).setCallback(new RequestCallback<ThreadTalkHistory>() {
    @Override
    public void onSuccess(ThreadTalkHistory thread) {
        if (thread == null) {
            Toast.makeText(SessionExtension.this, R.string.msg_history_empty, Toast.LENGTH_SHORT).show();
            return;
        }
        MsgHistoryActivity.startActivity(SessionExtension.this, thread.getReplyList());
    }

    @Override
    public void onFailed(int code) {
        Toast.makeText(SessionExtension.this, "失败:" + code, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onException(Throwable throwable) {
        Log.e(TAG, "pull server message exception:" + throwable);
    }
});

获取thread消息回复数

本地获取某thread消息的回复消息的条数。

/**
 * 本地获取某thread消息的回复消息的条数,thread消息不被计入总数
 *
 * @param msg thread中的某一条消息
 * @return 回复消息数
 */
int queryReplyCountInThreadTalkBlock(IMMessage msg);
参数 说明
msg thread中的某一条消息
int count = NIMClient.getService(MsgService.class).queryReplyCountInThreadTalkBlock(replymessage.get(0));

快捷评论

可以对消息进行快捷评论。评论内容并非一条消息,而是一个long类型,由上层指定评论内容与界面展示之间的联系

增加评论

/**
 * 增加一条快捷评论
 *
 * @param msg 回复对象
 * @param replyType 回复类型
 * @param ext 自定义扩展字段,最大8字符
 * @param needPush 是否需要推送
 * @param needBadge 是否需要角标
 * @param pushTitle 推送标题
 * @param pushContent 推送内容
 * @param pushPayload 第三方自定义的推送属性,限制json类型
 * @return InvocationFuture
 */
InvocationFuture<Long> addQuickComment(IMMessage msg, long replyType, String ext, boolean needPush, boolean needBadge, String pushTitle, String pushContent, Map<String, Object> pushPayload);
参数 说明
msg 回复对象
replyType 回复类型
ext 自定义扩展字段,最大8字符
needPush 是否需要推送
needBadge 是否需要角标
pushTitle 推送标题
pushContent 推送内容
pushPayload 第三方自定义的推送属性,限制json类型
NIMClient.getService(MsgService.class).addQuickComment(message, replytype, qcmsgExtEdit.getText().toString(), needpush, needbadge,
        pushTitleEdit.getText().toString(), pushContentEdit.getText().toString(), null).setCallback(new RequestCallback<Long>() {
    @Override
    public void onSuccess(Long param) {
        Toast.makeText(SessionExtension.this, "增加一条快捷评论成功", Toast.LENGTH_SHORT).show();
        showOnLog(logText, logJson.toString());
    }

    @Override
    public void onFailed(int code) {
        Toast.makeText(SessionExtension.this, "失败:" + code, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onException(Throwable exception) {
        Log.e(TAG, "pull server message exception:" + exception);
    }
});

删除评论

/**
 * 删除一条快捷评论
 *
 * @param msg 回复对象
 * @param replyType 回复类型
 * @param ext 自定义扩展字段,最大8字符
 * @param needPush 是否需要推送
 * @param needBadge 是否需要角标
 * @param pushTitle 推送标题
 * @param pushContent 推送内容
 * @param pushPayload 第三方自定义的推送属性,限制json类型
 * @return InvocationFuture
 */
InvocationFuture<Long> removeQuickComment(IMMessage msg, long replyType, String ext, boolean needPush, boolean needBadge, String pushTitle, String pushContent, Map<String, Object> pushPayload);
参数 说明
msg 回复对象
replyType 回复类型
ext 自定义扩展字段,最大8字符
needPush 是否需要推送
needBadge 是否需要角标
pushTitle 推送标题
pushContent 推送内容
pushPayload 第三方自定义的推送属性,限制json类型
NIMClient.getService(MsgService.class).removeQuickComment(message, replytype, qcmsgExtEdit.getText().toString(), needpush, needbadge,
        pushTitleEdit.getText().toString(), pushContentEdit.getText().toString(), null).setCallback(new RequestCallback<Long>() {
    @Override
    public void onSuccess(Long param) {
        Toast.makeText(SessionExtension.this, "删除一条快捷评论成功", Toast.LENGTH_SHORT).show();
        showOnLog(logText, logJson.toString());
    }

    @Override
    public void onFailed(int code) {
        Toast.makeText(SessionExtension.this, "失败:" + code, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onException(Throwable exception) {
        Log.e(TAG, "pull server message exception:" + exception);
    }
});

获取评论

/**
 * 获取快捷评论列表
 *
 * @param msgList 每个元素是被查询快捷评论的消息,数量不超过20
 * @return InvocationFuture
 */
InvocationFuture<List<QuickCommentOptionWrapper>> queryQuickComment(List<IMMessage> msgList);
参数 说明
msgList 每个元素是被查询快捷评论的消息,数量不超过20
NIMClient.getService(MsgService.class).queryQuickComment(msglist).setCallback(new RequestCallback<List<QuickCommentOptionWrapper>>() {
            @Override
            public void onSuccess(List<QuickCommentOptionWrapper> param) {
                showQuickComment(logText, logJson.toString());
            }

            @Override
            public void onFailed(int code) {

            }

            @Override
            public void onException(Throwable exception) {

            }
        });

收藏夹

允许用户添加一个20k以内的字符串作为收藏

添加一条收藏

/**
 * 添加一条收藏
 *
 * @param type 收藏类型
 * @param date 收藏内容,最大20k
 * @param ext 扩展字段,最大1k
 * @param uniqueId 去重唯一ID
 * @return InvocationFuture
 */
InvocationFuture<CollectInfo> addCollect(int type, String date, String ext, String uniqueId);
参数 说明
type 收藏类型
date 收藏内容,最大20k
ext 扩展字段,最大1k
uniqueId 去重唯一ID
NIMClient.getService(MsgService.class).addCollect(1, logJson.toString(), extEdit.getText().toString(), UniqueIdEdit.getText().toString()).setCallback(
        new RequestCallback<CollectInfo>() {
            @Override
            public void onSuccess(CollectInfo param) {
                Toast.makeText(SessionExtension.this, "添加收藏成功", Toast.LENGTH_SHORT).show();
                showOnLog(logText, logJson.toString());
            }

            @Override
            public void onFailed(int code) {
                Toast.makeText(SessionExtension.this, "失败:" + code, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onException(Throwable exception) {
                Log.e(TAG, "pull server message exception:" + exception);
            }
        }
);

批量移除收藏

/**
 * 批量移除收藏
 *
 * @param collectInfo 要移除的收藏的关键信息组成的列表,每一项为一个Pair,其中第一项为收藏的ID,第二项为收藏的创建时间
 * @see CollectInfo
 * @return InvocationFuture
 */
InvocationFuture<Integer> removeCollect(List<Pair<Long, Long>> collectInfo);
参数 说明
collectInfo 要移除的收藏的关键信息组成的列表,每一项为一个Pair,其中第一项为收藏的ID,第二项为收藏的创建时间
NIMClient.getService(MsgService.class).removeCollect(collectInfo).setCallback(
        new RequestCallback<Integer>() {
            @Override
            public void onSuccess(Integer param) {
                Toast.makeText(SessionExtension.this, "批量移除收藏成功", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailed(int code) {
                Toast.makeText(SessionExtension.this, "失败:" + code, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onException(Throwable exception) {
                Log.e(TAG, "pull server message exception:" + exception);
            }
        }
);

更新收藏的扩展字段

/**
 * 更新一个收藏的扩展字段
 *
 * @param infoId 要更新的收藏的ID
 * @param createTime 要更新的收藏的创建时间
 * @param ext 更新后的扩展字段
 * @return InvocationFuture
 */
InvocationFuture<CollectInfo> updateCollect(long infoId, long createTime, String ext);
参数 说明
infoId 要更新的收藏的ID
createTime 要更新的收藏的创建时间
ext 更新后的扩展字段
NIMClient.getService(MsgService.class).updateCollect(collectId,collectCreateTime,extEdit.getText().toString()).setCallback(new RequestCallback<CollectInfo>() {
    @Override
    public void onSuccess(CollectInfo param) {
        Toast.makeText(SessionExtension.this, "更新一个收藏的扩展字段成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onFailed(int code) {
        Toast.makeText(SessionExtension.this, "失败:" + code, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onException(Throwable exception) {
        Log.e(TAG, "pull server message exception:" + exception);
    }
});

分页查询收藏列表

/**
 * 从服务端分页查询收藏列表
 *
 * @param anchor 结束查询的最后一条收藏(不包含在查询结果中)
 * @param toTime 结束时间点单位毫秒
 * @param limit 本次查询的消息条数上限(最多100条)
 * @param direction 查询方向
 * @return InvocationFuture
 */
InvocationFuture<CollectInfoPage> queryCollect(CollectInfo anchor, long toTime, int limit, QueryDirectionEnum direction);
参数 说明
anchor 结束查询的最后一条收藏(不包含在查询结果中)
toTime 结束时间点单位毫秒
limit 本次查询的消息条数上限(最多100条)
direction 查询方向
NIMClient.getService(MsgService.class).queryCollect(null, tTime, limit, direction).setCallback(
        new RequestCallback<CollectInfoPage>() {
            @Override
            public void onSuccess(CollectInfoPage param) {
                if (param == null) {
                    Toast.makeText(SessionExtension.this, "从服务的分页查询收藏列表为空",
                            Toast.LENGTH_SHORT).show();
                    return;
                }
                addCollects(param.getCollectList());
            }

            @Override
            public void onFailed(int code) {

            }

            @Override
            public void onException(Throwable exception) {

            }
        }

        );

PIN标记

一条消息可以被所在会话的所有用户PIN,取消PIN和查询PIN,以及更新扩展字段。一条消息只能有一个PIN,多个用户PIN同一条消息时,较晚的PIN会覆盖较早的PIN

PIN一条消息

/**
 * PIN一条消息
 *
 * @param msg 被PIN的消息
 * @param ext 扩展字段
 * @return InvocationFuture
 */
InvocationFuture<Long> addMsgPin(IMMessage msg, String ext);
参数 说明
msg 被PIN的消息
ext 扩展字段
NIMClient.getService(MsgService.class).addMsgPin(message, pinmsgExtEdit.getText().toString()).setCallback(new RequestCallback<Long>() {
    @Override
    public void onSuccess(Long param) {
        Toast.makeText(SessionExtension.this, "PIN一条消息成功", Toast.LENGTH_SHORT).show();
        showOnLog(logText, logJson.toString());
    }

    @Override
    public void onFailed(int code) {
        Toast.makeText(SessionExtension.this, "失败:" + code, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onException(Throwable exception) {
        Log.e(TAG, "pull server message exception:" + exception);
    }
});

更新一条消息的PIN

/**
 * 更新一条消息的PIN
 *
 * @param msg 被PIN的消息
 * @param ext 扩展字段
 * @return InvocationFuture
 */
InvocationFuture<Long> updateMsgPin(IMMessage msg, String ext);
参数 说明
msg 被PIN的消息
ext 扩展字段
NIMClient.getService(MsgService.class).updateMsgPin(message, pinmsgExtEdit.getText().toString()).setCallback(new RequestCallback<Long>() {
    @Override
    public void onSuccess(Long param) {
        Toast.makeText(SessionExtension.this, "更新一条消息的PIN成功", Toast.LENGTH_SHORT).show();
        showOnLog(logText, logJson.toString());
    }

    @Override
    public void onFailed(int code) {
        Toast.makeText(SessionExtension.this, "失败:" + code, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onException(Throwable exception) {
        Log.e(TAG, "pull server message exception:" + exception);
    }
});

移除一条消息的PIN

/**
 * 移除一条消息的PIN
 *
 * @param msg 被PIN的消息
 * @param ext 扩展字段
 * @return InvocationFuture
 */
InvocationFuture<Long> removeMsgPin(IMMessage msg, String ext);
参数 说明
msg 被PIN的消息
ext 扩展字段
NIMClient.getService(MsgService.class).removeMsgPin(message, pinmsgExtEdit.getText().toString()).setCallback(new RequestCallback<Long>() {
    @Override
    public void onSuccess(Long param) {
        Toast.makeText(SessionExtension.this, "移除一条消息的PIN成功", Toast.LENGTH_SHORT).show();
        showOnLog(logText, logJson.toString());
    }

    @Override
    public void onFailed(int code) {
        Toast.makeText(SessionExtension.this, "失败:" + code, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onException(Throwable exception) {
        Log.e(TAG, "pull server message exception:" + exception);
    }
});

同步会话的PIN信息

/**
 * 同步会话的PIN信息
 *
 * @param sessionType 会话类型
 * @param sessionId   会话ID
 * @param timestamp   时间戳,同步时间戳以后的PIN
 * @return InvocationFuture
 */
InvocationFuture<MsgPinSyncResponseOptionWrapper> syncMsgPin(SessionTypeEnum sessionType, String sessionId, long timestamp);
参数 说明
sessionType 会话类型
sessionId 会话ID
timestamp 时间戳,同步时间戳以后的PIN
NIMClient.getService(MsgService.class).syncMsgPin(getSessionType(), receiverEdit.getText().toString(), 0).setCallback(new RequestCallback<MsgPinSyncResponseOptionWrapper>() {
    @Override
    public void onSuccess(MsgPinSyncResponseOptionWrapper msgPinSync) {
        if (msgPinSync == null) {
            Toast.makeText(SessionExtension.this, "从服务端查询会话的PIN信息为空",
                    Toast.LENGTH_SHORT).show();
            return;
        }
        if (!msgPinSync.isChanged()) {
            Toast.makeText(SessionExtension.this, "没有变化", Toast.LENGTH_SHORT).show();
            return;
        }
        ArrayList<IMMessage> msgList = new ArrayList<>();
        for (MsgPinSyncResponseOption infoList : msgPinSync.getMsgPinInfoList()) {
            String uuid = infoList.getKey().getUuid();
            IMMessage msg = MsgDBHelper.queryMessageByUuid(uuid);
            if (msg == null) {
                continue;
            }
            msgList.add(msg);
        }
        MsgHistoryActivity.startActivity(SessionExtension.this, msgList);
    }

    @Overridetong
    public void onFailed(int code) {

    }

    @Override
    public void onException(Throwable exception) {

    }
});

获取PIN消息列表

/**
 * 本地获取会话的PIN消息列表
 *
 * @param sessionId 会话ID
 * @param sessionType 会话类型
 * @return PIN消息列表
 */
List<MsgPinDbOption> queryMsgPinBlock(String sessionId, SessionTypeEnum sessionType);
参数 说明
sessionId 会话ID
sessionType 会话类型
List<MsgPinDbOption> msgPinDbOptions = NIMClient.getService(MsgService.class).queryMsgPinBlock(receiverEdit.getText().toString(), getSessionType());

会话置顶

添加一个置顶会话

/**
 * 添加一个置顶会话
 *
 * @param sessionId   会话ID
 * @param sessionType 会话类型
 * @param ext         扩展字段,最大512字符
 * @return InvocationFuture
 */
InvocationFuture<StickTopSessionInfo> addStickTopSession(String sessionId, SessionTypeEnum sessionType, String ext);
参数 说明
sessionId 会话ID
sessionType 会话类型
ext 扩展字段,最大512字符
NIMClient.getService(MsgService.class).addStickTopSession(receiverEdit.getText().toString(), getSessionType(), extEdit.getText().toString()).setCallback(
        new RequestCallback<StickTopSessionInfo>() {
            @Override
            public void onSuccess(StickTopSessionInfo param) {
                Toast.makeText(SessionExtension.this, "添加一个置顶会话成功", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailed(int code) {
                Toast.makeText(SessionExtension.this, "失败:" + code, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onException(Throwable exception) {
                Log.e(TAG, "pull server message exception:" + exception);
            }
        }
);

删除一个置顶会话

/**
 * 删除一个置顶会话
 *
 * @param sessionId   会话ID
 * @param sessionType 会话类型
 * @param ext         扩展字段,最大512字符
 * @return InvocationFuture
 */
InvocationFuture<Void> removeStickTopSession(String sessionId, SessionTypeEnum sessionType, String ext);
参数 说明
sessionId 会话ID
sessionType 会话类型
ext 扩展字段,最大512字符
NIMClient.getService(MsgService.class).removeStickTopSession(receiverEdit.getText().toString(), getSessionType(), extEdit.getText().toString()).setCallback(
        new RequestCallback<Void>() {
            @Override
            public void onSuccess(Void param) {
                Toast.makeText(SessionExtension.this, "删除一个置顶会话成功", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailed(int code) {
                Toast.makeText(SessionExtension.this, "失败:" + code, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onException(Throwable exception) {
                Log.e(TAG, "pull server message exception:" + exception);
            }
        }
);

更新扩展字段

/**
 * 更新一个会话在置顶上的扩展字段
 *
 * @param sessionId   会话ID
 * @param sessionType 会话类型
 * @param ext         扩展字段,最大512字符
 * @return InvocationFuture
 */
InvocationFuture<StickTopSessionInfo> updateStickTopSession(String sessionId, SessionTypeEnum sessionType, String ext);
参数 说明
sessionId 会话ID
sessionType 会话类型
ext 扩展字段,最大512字符
NIMClient.getService(MsgService.class).updateStickTopSession(receiverEdit.getText().toString(), getSessionType(), extEdit.getText().toString()).setCallback(
        new RequestCallback<StickTopSessionInfo>() {
            @Override
            public void onSuccess(StickTopSessionInfo param) {
                Toast.makeText(SessionExtension.this, "更新一个会话在置顶上的扩展字段成功", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailed(int code) {
                Toast.makeText(SessionExtension.this, "失败:" + code, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onException(Throwable exception) {
                Log.e(TAG, "pull server message exception:" + exception);
            }
        }
);

获取置顶会话列表

/**
 * 获取置顶会话信息的列表
 *
 * @return 置顶信息列表
 */
List<StickTopSessionInfo> queryStickTopSessionBlock();
List<StickTopSessionInfo> sticktopsession = NIMClient.getService(MsgService.class).queryStickTopSessionBlock();