拦截消息
IMKit 支持设置消息拦截器 MessageInterceptor,可在消息发送前、发送后、接收时、插入本地 数据库前进行拦截,方便您进行自定义处理。
消息拦截器说明
MessageInterceptor 是一个接口类,包含以下方法。
| 方法 | 说明 | 
|---|---|
| interceptOnSendMessage | 拦截待发送的消息。该方法可拦截 Message 对象。 | 
| interceptOnSentMessage | 拦截发送成功的消息。该方法可拦截 Message 对象。 | 
| interceptOnInsertOutgoingMessage | interceptOnInsertOutgoingMessage 拦截待插入 本地消息数据库的发送方向的消息的消息内容,提供两个重载方法:
  | 
| interceptOnInsertIncomingMessage | 拦截待插入本地消息数据库的接收方向的消息的消息内容。 | 
| interceptReceivedMessage | 拦截接收的消息。SDK 连接后将先接收离线消息。 hasPackage 标识是否还有剩余的离线消息包,left 表示当前正在接收的离线消息包剩余多少条。hasPackage 为 false 且 left 为 0 表示离线消息已接收完毕,当前拦截的消息为实时消息。该方法可拦截 Message 对象。 | 
在上述所有方法中返回 false 表示 App 仅需要拦截处理,处理完毕后由 SDK 完成后续流程。返回 true 表示 App 需要在拦截后 自行处理后续流程,例如 App 希望在处理完毕后自行发送修改后的消息,可返回 true。
设置消息拦截器
使用 IMCenter 的 setMessageInterceptor 设置消息拦截器。代码示例说明如下:
- 在 
interceptOnSendMessage方法中拦截并修改消息推送内容 - 在 
interceptOnInsertOutgoingMessage方法中拦截并修改图片和 GIF 消息扩展 
Java
private void initInterceptor() {
    IMCenter.getInstance().setMessageInterceptor(
    new MessageInterceptor() {
        @Override
        public boolean interceptReceivedMessage(
            Message message,
            int left,
            boolean hasPackage,
            boolean offline) {
            return false;
        }
        @Override
        public boolean interceptOnSendMessage(Message message) {
            MessageContent messageContent = message.getContent();
            String language = mContext.getResources().getConfiguration().locale.getLanguage();
            if (language.endsWith("en")) { // 手机系统语言为英文
                if (messageContent instanceof VoiceMessage) {
                    MessagePushConfig messagePushConfig = message.getMessagePushConfig();
                    if (messagePushConfig == null){
                        messagePushConfig = new MessagePushConfig();
                        message.setMessagePushConfig(messagePushConfig);
                    }
                    messagePushConfig.setPushContent("[voice]");// 语音消息时推送显示为 "\[voice\]"
                }
            }
            return false;
            }
        @Override
        public boolean interceptOnSentMessage(Message message) {
            if (message != null) {
            message.setMessageConfig(null);
            }
            return false;
        }
        @Override
        public boolean interceptOnInsertOutgoingMessage(
            Conversation.ConversationType type,
            String targetId,
            Message.SentStatus sentStatus,
            MessageContent content,
            long time) {
            return false;
            }
        @Override
            public boolean interceptOnInsertOutgoingMessage(Conversation.ConversationType type, String targetId, Message.SentStatus sentStatus,
                                                            MessageContent content, long time, RongIMClient.ResultCallback<Message> callback) {
               //含 UI 集成设置图片消息可扩展时,此方法 return true,构建 message 将可扩展属性设置为 true,并调用 callback.onSuccess(message);
                Message message=Message.obtain(targetId,type,content);
                message.setCanIncludeExpansion(true);
                callback.onSuccess(message);
                return true;
            }
        @Override
        public boolean interceptOnInsertIncomingMessage(
            Conversation.ConversationType type,
            String targetId,
            String senderId,
            Message.ReceivedStatus receivedStatus,
            MessageContent content,
            long time) {
            return false;
            }
        });
        }
如何拦截 IMKit 内置会话页面发送的图片和 GIF 消息
提示
要求 SDK 版本 ≧ 5.2.4。
使用 IMKit 内置会话页面发送图片和 GIF 消息时,SDK 会先在内部调用插入消息方法将消息插入本地消息数据库,再调用发送消息方法。如果应用程序有以下需求:
- 对图片消息和 GIF 消息设置消息扩展,需要打开图片消息和 GIF 消息的可扩展属性(
setCanIncludeExpansion(true))。 - 修改图片消息和 GIF 消息的部分数据,例  如缩略图、或者消息内容体内的 
extra字段等。 - 彻底拦截图片消息和 GIF 消息,由应用程序自定义处理。
 
必须在消息插入本地数据库前拦截图片、GIF 消息,使用以下方法进行拦截:
Java
default boolean interceptOnInsertOutgoingMessage(
        Conversation.ConversationType type,
        String targetId,
        Message.SentStatus sentStatus,
        MessageContent content,
        long time,
        RongIMClient.ResultCallback<Message> callback)
应用程序处理完毕后:
- 如需 SDK 继续发送被拦截的消息,需要调用 
callback.onSuccess(message)表示交给 SDK 继续发送该消息,此时必须在interceptOnInsertOutgoingMessage方法中返回true,否则会发出两条内容重复的消息。 - 如需彻底拦截,则调用 
callback.onError(IRongCoreEnum.CoreErrorCode.PARAMETER_ERROR),并在interceptOnInsertOutgoingMessage中返回true。