自定义消息收发
更新时间: 2024/03/15 16:12:31
除了内置消息类型以外,网易云信 NIM Android SDK 还支持收发自定义消息。
功能介绍
SDK 不负责定义和解析自定义消息的具体内容,解析工作由开发者完成。SDK 会将自定义消息存入消息数据库,会和内置消息一并展现在消息记录中。
为了使用更加方便,自定义消息采用附件的方式展示给开发者。体现在IMMessage
类中,自定义消息的内容会被解析为MsgAttachment
对象。由于 SDK 并不知道自定义消息的格式,您的应用需要注册一个自定义消息解析器。当您的应用调用查询消息历史的方法,或者 SDK 收到消息通知您的应用时,就能将自定义消息内容转换为一个MsgAttachment
对象,然后就可参考多媒体消息收发的实现方式,实现自定义消息的收发。
MsgAttachment
的长度上限为 5000 字符。
前提条件
- 已初始化 SDK。
- (如发送的为群聊消息)已创建群组。
API使用限制
发送消息(sendMessage
)的方法调用存在频控,一分钟内默认最多可调用 300 次。
实现方法
以下给出了两个自定义消息实现的示例。您也可以参照 视频教程:自定义消息集成 了解实现方法。
示例:剪刀石头布
本节以“剪刀石头布”的游戏为例,介绍实现自定义消息收发的流程。
-
定义一个自定义消息附件的基类,负责解析您的自定义消息的公用字段,比如类型等。还可以定义一些公共接口,用于一些便利性的调用。
实现
MsgAttachment
接口的成员都要实现 Serializable。java
// 先定义一个自定义消息附件的基类,负责解析你的自定义消息的公用字段,比如类型等等。 public abstract class CustomAttachment implements MsgAttachment { // 自定义消息附件的类型,根据该字段区分不同的自定义消息 protected int type; CustomAttachment(int type) { this.type = type; } // 解析附件内容。 public void fromJson(JSONObject data) { if (data != null) { parseData(data); } } // 实现 MsgAttachment 的接口,封装公用字段,然后调用子类的封装函数。 @Override public String toJson(boolean send) { return CustomAttachParser.packData(type, packData()); } // 子类的解析和封装接口。 protected abstract void parseData(JSONObject data); protected abstract JSONObject packData(); }
-
继承这个基类,实现“剪刀石头布”的附件类型。
成员变量都要实现 Serializable。
java
public class GuessAttachment extends CustomAttachment { // 猜拳类型枚举 public enum Guess { Shitou(1), Jiandao(2), Bu(3), ; } private Guess value; public GuessAttachment() { super(CustomAttachmentType.Guess); random(); } // 解析猜拳类型具体数据 @Override protected void parseData(JSONObject data) { value = Guess.enumOfValue(data.getIntValue("value")); } // 数据打包 @Override protected JSONObject packData() { JSONObject data = new JSONObject(); data.put("value", value.getValue()); return data; } private void random() { int value = new Random().nextInt(3) + 1; this.value = Guess.enumOfValue(value); } }
-
实现自定义消息的附件解析器。
java
public class CustomAttachParser implements MsgAttachmentParser { // 根据解析到的消息类型,确定附件对象类型 @Override public MsgAttachment parse(String json) { CustomAttachment attachment = null; try { JSONObject object = JSON.parseObject(json); int type = object.getInteger("type"); JSONObject data = object.getJSONObject(KEY_DATA); switch (type) { case CustomAttachmentType.Guess: attachment = new GuessAttachment(); break; default: attachment = new DefaultCustomAttachment(); break; } if (attachment != null) { attachment.fromJson(data); } } catch (Exception e) { } return attachment; } public static String packData(int type, JSONObject data) { JSONObject object = new JSONObject(); object.put(KEY_TYPE, type); if (data != null) { object.put(KEY_DATA, data); } return object.toJSONString(); } }
-
将该附件解析器注册到 SDK 中。为了保证生成历史消息时能够正确解析自定义附件,注册一般应放在 Application 的 onCreate 中 的主进程判断语句内完成。
java
if (NIMUtil.isMainProcess(this)) { // 监听的注册,必须在主进程中。 NIMClient.getService(MsgService.class).registerCustomAttachmentParser(new CustomAttachParser()); }
-
参考多媒体消息收发的实现方式,实现自定义消息的收发。
示例:阅后即焚
若需要发送文件类型消息,例如图片等,可以参考阅后即焚的实现。具体实现步骤如下:
-
定义一个自定义的附件类型,并继承
FileAttachment
。注意,成员变量都要实现 Serializable。java
public class SnapChatAttachment extends FileAttachment { private static final String KEY_PATH = "path"; private static final String KEY_SIZE = "size"; private static final String KEY_MD5 = "md5"; private static final String KEY_URL = "url"; public SnapChatAttachment() { super(); } public SnapChatAttachment(JSONObject data) { load(data); } @Override public String toJson(boolean send) { JSONObject data = new JSONObject(); try { // 重发使用本地路径 if (!send && !TextUtils.isEmpty(path)) { data.put(KEY_PATH, path); } if (!TextUtils.isEmpty(md5)) { data.put(KEY_MD5, md5); } // 注意:这段代码一定要写。 // SDK在调toJson的时候 父类FileAttachemnt的url才有值。 // 这个值是sdk自动赋值的。 data.put(KEY_URL, url); data.put(KEY_SIZE, size); } catch (Exception e) { e.printStackTrace(); } return CustomAttachParser.packData(CustomAttachmentType.SnapChat, data); } private void load(JSONObject data) { path = data.getString(KEY_PATH); md5 = data.getString(KEY_MD5); url = data.getString(KEY_URL); size = data.containsKey(KEY_SIZE) ? data.getLong(KEY_SIZE) : 0; } }
-
实现自定义消息的附件解析器。
java
public class CustomAttachParser implements MsgAttachmentParser { // 根据解析到的消息类型,确定附件对象类型 @Override public MsgAttachment parse(String json) { CustomAttachment attachment = null; try { JSONObject object = JSON.parseObject(json); int type = object.getInteger("type"); JSONObject data = object.getJSONObject(KEY_DATA); switch (type) { case CustomAttachmentType.SnapChat: return new SnapChatAttachment(data); default: attachment = new DefaultCustomAttachment(); break; } if (attachment != null) { attachment.fromJson(data); } } catch (Exception e) { } return attachment; } ... }
-
将该附件解析器注册到 SDK 中。为了保证生成历史消息时能够正确解析自定义附件,注册一般应放在 Application 的 onCreate 中完成。
java
if (NIMUtil.isMainProcess(this)) { // 监听的注册,必须在主进程中。 NIMClient.getService(MsgService.class).registerCustomAttachmentParser(new CustomAttachParser()); }
-
参考多媒体消息收发的实现方式,实现自定义消息的收发。
API参考
SDK 的MessageBuilder
类提供多个构建自定义消息的方法,具体如下:
参考文档
本文档介绍的是不含 UI 的自定义消息收发实现流程,若需要实现含 UI 的自定义消息收发,请参考 UIKit 相关文档:实现自定义消息收发