Android

发送自定义消息

更新时间: 2025/09/11 14:15:56

网易云信 IM UIKit 内置了多种基本消息类型,包括文本、图片、语音、视频、文件等,可满足大部分即时通讯场景。当这些基础消息类型无法满足您的业务需求时,您可以使用自定义消息来扩展功能,例如实现电商订单卡片、红包、系统通知等。

发送自定义消息

实现自定义消息收发之前,您需先自行实现消息数据的封装和相关解析规则。IM UIKit 可按照您实现的封装和解析规则对消息进行处理,将消息返回给您的应用。

第一步:实现自定义消息类

创建自定义 Attachment,需要继承 CustomAttachment,并重写数据解析方法(parse)、数据封装方法(packData)以及序列化方法(toJsonStr)。

  • 必须提供无参构造方法: 自定义的 Attachment 必须提供一个无参数的构造方法,因为 IM UIKit 内部会通过反射方式创建对象。
  • 必须调用父类构造方法传入类型: 在构造方法中,必须调用父类的构造方法并传入自定义消息类型值(建议从 1000 开始)。
Javapublic class CustomerSampleAttachment extends CustomAttachment {
    // 定义消息类型常量,建议从1000开始
    private static final int TYPE = 1002;

    // 自定义消息解析后的值,本例代表自定义消息只有一个 String 类型的值
    private String customerText;

    // 必须提供无参构造方法,IM UIKit 内部会通过反射方式创建对象
    public CustomerSampleAttachment() {
        super(TYPE); // 调用父类构造方法并传入消息类型
    }

    // 重写数据解析方法,这里面数据以 JSONObject 格式进行传输
    @Override
    protected void parseData(JSONObject data) {
        try {
            this.customerText = data.getString("customer_message_key");
        } catch (Exception exception) {
        }
    }

    // 重写数据封装方法,将您需要传递的内容转换为 JSONObject 格式
    @Override
    protected JSONObject packData() {
        JSONObject data = new JSONObject();
        try {
            data.put("customer_message_key", customerText);
        } catch (Exception exception) {
        }
        return data;
    }

    public void setData(String data) {
        this.customerText = data;
    }

    // 设置自定义消息的信息摘要,用于会话列表展示
    @Override
    public String getContent() {
        return "您的自定义消息...";
    }

    // 将自定义数据序列化为JSON字符串
    @NonNull
    @Override
    public String toJsonStr() {
        try {
            JSONObject map = new JSONObject();
            map.put("type", TYPE);
            map.put("data", packData());
            return map.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}

第二步:增加自定义消息映射关系

在消息数据处理逻辑中,增加自定义消息的映射关系。所有自定义消息都会在 ChatCustomMsgFactory 中进行分发,SDK 将确定您的自定义消息是采用哪个 CustomAttachment 并进行处理。

Java// 在 IM UIKit 初始化后添加映射关系
ChatKitClient.addCustomAttach(1002, CustomerSampleAttachment.class);

第三步:创建并发送自定义消息

创建自定义消息需要先实例化自定义 Attachment 类,然后使用 createCustomMessage 方法创建 V2NIMMessage 对象,最后通过 ChatRepo.sendMessage 方法发送。

Java// 创建自定义 Attachment 对象
CustomerSampleAttachment customerAttachment = new CustomerSampleAttachment();
// 设置 Attachment 中的数据
customerAttachment.setData("your data");
// 将 Attachment 序列化为字符串
String attachStr = customerAttachment.toJsonStr();

// 创建用于发送的 V2NIMMessage
V2NIMMessage customMsg = V2NIMMessageCreator.createCustomMessage("这是一个自定义消息", attachStr);

// 获取会话ID
String conversationId = "your_conversation_id";
// 调用 ChatRepo 提供的发送接口
ChatRepo.sendMessage(customMsg, conversationId, null, new Callback<Void>() {
    @Override
    public void onResult(int code, Void result, Throwable exception) {
        if (code == 0) {
            // 消息发送成功
        } else {
            // 消息发送失败
        }
    }
});

注意事项

当通过服务端 API 发送自定义消息时,为确保客户端能够正确识别和解析不同类型的自定义消息,您需要按照特定格式构造 attachment 字段的 JSON 内容。自定义消息的 attachment 字段应遵循以下 JSON 格式:

JSON{
    "type": 1002,   //Integer,自定义消息类型标识,用于客户端区分不同类型的自定义消息,必须与客户端定义的类型保持一致
    "data": {       //JSON,对象自定义消息的业务数据载体,可包含任意自定义的键值对
    "customer\_message\_key": "这是一条自定义消息"   
    }
}

自定义消息 UI 展示

若需要在会话界面将自定义消息按照您自定义的 UI 样式进行展示,请完成以下步骤。

实现自定义 ViewHolder

添加消息展示的 ViewHolder,并使其继承 NormalChatBaseMessageViewHolder

若集成了通用版 UI 组件,需要使其继承 FunChatBaseMessageViewHolder(通用版)。也可参考 FunChatTextMessageViewHolderFunChatImageMessageViewHolder 等已实现的代码逻辑。

Javapublic class CustomerSampleViewHolder extends NormalChatBaseMessageViewHolder {

    private CustomerSampleViewBinding binding;

    public CustomerSampleViewHolder(@NonNull ChatBaseMessageViewHolderBinding parent, int viewType) {
        super(parent, viewType);
    }

    @Override
    public void addViewToMessageContainer() {
        // 创建自己的 layout 布局,例如 R.layout.item_custom_evaluation
        binding = CustomerSampleViewBinding.inflate(LayoutInflater.from(parent.getContext()),
                getContainer(), true);
    }

    @Override
    public void bindData(ChatMessageBean message, ChatMessageBean lastMessage) {
        super.bindData(message, lastMessage);
        currentMessage = message;
        // 获取自定义消息的 Attachment
        CustomerSampleAttachment attachment = (CustomerSampleAttachment) message.getMessageData().getAttachment();
        if (attachment == null) {
            return;
        }
        // 根据 attachment 中的数据设置 ViewHolder 的 UI
        // 例如:binding.myTextView.setText(attachment.getData());
    }
}

自定义消息去除头像

需要在自定义消息的 ViewHolder 中重写 onCommonViewVisibleConfig,在该方法中控制头像信息的显示。

Javaprotected void onCommonViewVisibleConfig(ChatMessageBean messageBean) {
    baseViewBinding.otherUsername.setVisibility(View.GONE);
    baseViewBinding.otherUserAvatar.setVisibility(View.GONE);
    baseViewBinding.myAvatar.setVisibility(View.GONE);
    baseViewBinding.myName.setVisibility(View.GONE);
    baseViewBinding.messageStatus.setVisibility(View.GONE);
}

调整消息内容布局

若需要调整消息内容的布局,如消息内容居中显示,可以重写 ViewHolder的onLayoutConfig 方法。

Java@Override
protected void onLayoutConfig(ChatMessageBean messageBean) {
    // 1. 获取messageContentGroup当前布局参数
    ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) baseViewBinding.messageContentGroup.getLayoutParams();

    // 2. 清除原有约束
    params.startToEnd = ConstraintLayout.LayoutParams.UNSET;   // 清除与otherUserAvatar的关联
    params.endToStart = ConstraintLayout.LayoutParams.UNSET;    // 清除与myAvatar的关联

    // 3. 设置新的约束使其充满父布局
    params.startToStart = ConstraintLayout.LayoutParams.PARENT_ID; // 左边对齐父布局
    params.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;    // 右边对齐父布局
    params.matchConstraintPercentWidth = 0.9f;                    // 设置宽度百分比为100%
    params.matchConstraintDefaultWidth = ConstraintLayout.LayoutParams.MATCH_CONSTRAINT_PERCENT; // 宽度百分比适应内容
    // 4. 应用新的布局参数
    baseViewBinding.messageContentGroup.setLayoutParams(params);

    // 1. 获取messageContentGroup当前布局参数
    ConstraintLayout.LayoutParams messageParams = (ConstraintLayout.LayoutParams) baseViewBinding.messageContainer.getLayoutParams();
    messageParams.matchConstraintPercentWidth = 1f;                    // 设置宽度百分比为100%
    messageParams.matchConstraintDefaultWidth = ConstraintLayout.LayoutParams.MATCH_CONSTRAINT_PERCENT; // 宽度百分比适应内容
    // 2. 应用新的布局参数
    baseViewBinding.messageContainer.setLayoutParams(messageParams);
}

注册自定义 ViewHolder

CustomerSampleViewHolder 添加到 IM UIKit,使其在加载后能够处理您的自定义消息。

Java// 在 IM UIKit 初始化后注册
ChatKitClient.addCustomViewHolder(1002, CustomerSampleViewHolder.class);

接收消息

IM UIKit 中已实现消息接收逻辑,如果您需要接收消息实现自己其他的业务逻辑,只需注册消息监听器即可。

Javaprivate final NEChatListener messageListener =
  new NEChatListener() {
        // 接收到新消息
        @Override
        public void onReceiveMessages(@NonNull List<IMMessageInfo> messages) {
            // 处理收到的消息
        }
    };

// 注册消息接收监听
ChatRepo.addMessageListener(messageListener);
此文档是否对你有帮助?
有帮助
去反馈
  • 发送自定义消息
  • 第一步:实现自定义消息类
  • 第二步:增加自定义消息映射关系
  • 第三步:创建并发送自定义消息
  • 注意事项
  • 自定义消息 UI 展示
  • 实现自定义 ViewHolder
  • 自定义消息去除头像
  • 调整消息内容布局
  • 注册自定义 ViewHolder
  • 接收消息