在即时通讯 IM 日益普及的今天,用户对隐私保护的需求催生了一种独特的消息模式——"阅后即焚",其核心机制是通过自动销毁已读消息来实现隐私保护。它不仅在社交领域广泛应用,在金融、医疗、企业协作等对数据安全要求更高的场景中也发挥着重要作用。
本文将手把手教大家如何基于环信 IM SDK实现“阅后即焚“功能的开发。
技术原理
“阅后即焚”功能基于环信 SDK 的消息扩展机制和 已读回执功能实现,工作流程如下:
- 发送消息:用户 A 创建消息时,通过消息扩展字段添加阅后即焚标识,然后将消息发送给用户 B。
- 接收与删除消息:用户 B 收到消息后,解析消息扩展字段查看是否有阅后即焚标识。若有, 用户B查看消息后,发送已读回执且删除用户B该条消息。
- 发送方删除消息:用户 A 收到已读回执后,检查原消息是否带有阅后即焚标识。若是,删除用户 A 该条消息并更新显示。
实现过程
本节以Android端文本消息为例介绍阅后即焚方案的实现过程。对于图片、语音、视频等其他消息类型,均可参照此流程进行类似实现。
准备工作
发送阅后即焚消息
以下为发送阅后即焚消息的示例代码,通过 消息扩展字段 添加阅后即焚标识。
// 阅后即焚标识(这里只是举例,你可以自定义具体字段)
private final String FIRE_FLAG = "fire";
// 创建文本消息,toChatUsername 为接收方用户 ID
EMMessage message = EMMessage.createTextSendMessage("这是一条阅后即焚消息", toChatUsername);
// 设置为单聊
message.setChatType(EMMessage.ChatType.Chat);
// 设置消息扩展字段传递阅后即焚标识
message.setAttribute(FIRE_FLAG, true);
// 发送消息
EMClient.getInstance().chatManager().sendMessage(message);
接收和删除消息
收到消息后,判断是否为阅后即焚消息。若是,在用户查看消息后发送已读回执并删除该条阅后即焚消息。
// 阅后即焚标识(这里只是举例,你可以自定义具体字段)
private final String FIRE_FLAG = "fire";
// 注册消息监听器
EMMessageListener msgListener = new EMMessageListener() {
@Override
public void onMessageReceived(List<EMMessage> messages) {
for (EMMessage message : messages) {
// 判断是否为阅后即焚消息
// 使用 getBooleanAttribute(key, defaultValue) 避免捕获 HyphenateException
if (message.getBooleanAttribute(FIRE_FLAG, false)) {
// 更新 UI,提示用户有一条阅后即焚消息
}
}
}
// 其他回调方法...
@Override
public void onCmdMessageReceived(List<EMMessage> messages) {}
@Override
public void onMessageRead(List<EMMessage> messages) {}
@Override
public void onMessageDelivered(List<EMMessage> messages) {}
@Override
public void onMessageRecalledWithExt(List<EMRecallMessageInfo> recallMessageInfo) {}
@Override
public void onMessageChanged(EMMessage message, Object change) {}
};
EMClient.getInstance().chatManager().addMessageListener(msgListener);
// 当用户已读消息后(例如,点击查看了详情),发送已读回执并删除服务器和本地消息
try {
// 发送已读回执
EMClient.getInstance().chatManager().ackMessageRead(message.getFrom(), message.getMsgId());
// 获取消息所属会话
EMConversation conversation = EMClient.getInstance().chatManager().getConversation(message.getFrom(), EMConversation.EMConversationType.Chat, true);
// 删除服务端和本地消息
ArrayList msgIds = new ArrayList<>();
msgIds.add(message.getMsgId());
conversation.removeMessagesFromServer(msgIds, new EMCallBack() {
@Override
public void onSuccess() {
//删除成功
// 刷新你的数据集,更新 UI
}
@Override
public void onError(int code, String error) {
//删除失败
//用户根据自己的业务需求进行处理
}
});
} catch (HyphenateException e) {
e.printStackTrace();
}
发送方删除消息
发送方收到回执后,判断该消息是否阅后即焚。若是,删除该条阅后即焚消息。
// 注册消息监听器
EMMessageListener msgListener = new EMMessageListener() {
@Override
// 收到已读回执的回调
public void onMessageRead(List<EMMessage> messages) {
for (EMMessage message : messages) {
// 判断是否为阅后即焚消息
if (message.getBooleanAttribute(FIRE_FLAG, false)) {
// 消息所属会话:会话 ID 为接收方的用户 ID
EMConversation conversation = EMClient.getInstance().chatManager().getConversation(message.getTo(), EMConversation.EMConversationType.Chat, true);
// 删除服务端和本地消息
ArrayList msgIds = new ArrayList<>();
msgIds.add(message.getMsgId());
conversation.removeMessagesFromServer(msgIds, new EMCallBack() {
@Override
public void onSuccess() {
//删除成功
// 刷新你的数据集,更新 UI
}
@Override
public void onError(int code, String error) {
//删除失败
//用户根据自己的业务需求进行处理
}
});
}
}
}
// 其他回调方法...
@Override
public void onMessageReceived(List<EMMessage> messages) {}
@Override
public void onCmdMessageReceived(List<EMMessage> messages) {}
@Override
public void onMessageDelivered(List<EMMessage> messages) {}
@Override
public void onMessageRecalledWithExt(List<EMRecallMessageInfo> recallMessageInfo) {}
@Override
public void onMessageChanged(EMMessage message, Object change) {}
};
EMClient.getInstance().chatManager().addMessageListener(msgListener);
注意事项
为避免内存泄漏,务必在 Activity 销毁时移除已注册的监听器
// 在 Activity 中
@Override
protected void onDestroy() {
// 移除消息监听器
if (msgListener != null) {
EMClient.getInstance().chatManager().removeMessageListener(msgListener);
}
super.onDestroy();
}
本次基于环信SDK的实战开发,我们实现了IM消息“阅后即焚“功能。如开发中遇到其他问题,请至 环信官网 联系技术支持咨询。