在即時通訊 IM 日益普及的今天,用戶對隱私保護的需求催生了一種獨特的消息模式——“閱后即焚”,其核心機制是通過自動銷毀已讀消息來實現隱私保護。它不僅在社交領域廣泛應用,在金融、醫療、企業協作等對數據安全要求更高的場景中也發揮著重要作用。

本文將手把手教大家如何基于環信 IM SDK實現“閱后即焚“功能的開發。

技術原理

“閱后即焚”功能基于環信 SDK 的消息擴展機制和 已讀回執功能實現,工作流程如下:
在這里插入圖片描述

  1. 發送消息:用戶 A 創建消息時,通過消息擴展字段添加閱后即焚標識,然后將消息發送給用戶 B。

  2. 接收與刪除消息:用戶 B 收到消息后,解析消息擴展字段查看是否有閱后即焚標識。若有, 用戶B查看消息后,發送已讀回執且刪除用戶B該條消息。

  3. 發送方刪除消息:用戶 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 中@Overrideprotected void onDestroy() {
    
    // 移除消息監聽器
    if (msgListener != null) {
        EMClient.getInstance().chatManager().removeMessageListener(msgListener);
    }
    super.onDestroy();}

本次基于環信SDK的實戰開發,我們實現了IM消息“閱后即焚“功能。如開發中遇到其他問題,請至 環信官網 聯系技術支持咨詢。

參考文檔: