• UIKit
  • SDK
  • 服务端 API
Chat/
SDK/
Android/
消息/
SDK
  • 集成 SDK
  • 初始化
  • 登录登出
  • 消息
    • 介绍
    • 发送消息
    • 接收消息
    • 历史消息
    • 转发消息
    • 消息变更
    • 插入消息
    • 删除消息
    • 清空消息
    • 撤回消息
    • 在线消息
    • 已读回执
    • 查询消息
    • 群 @ 消息
    • 群定向消息
    • 消息免打套
    • 消息扩展
    • 消息回应
    • 消息翻译
    • 消息置顶
  • 会话
    • 介绍
    • 会话列表
    • 获取会话
    • 会话未读数
    • 置顶会话
    • 删除会话
    • 会话草稿
    • 会话标记
    • 会话分组
  • 群组
    • 介绍
    • 管理群组
    • 群资料
    • 管理群成员
    • 群成员资料
    • 自定义属性
    • 群计数器
  • 社群话题
    • 管理社群
    • 权限组
  • 用户
    • 用户资料
    • 用户状态
    • 管理好友
    • 好友分组
    • 黑名单
    • 关注与粉丝
  • 本地搜索
    • 搜索消息
    • 搜索好友
    • 搜索群组
    • 搜索群成员
  • 信令
  • 客户端 API
    • Java
  • 开发指引
  • 控制台指南
    • 创建和升级应用
    • 基本配置
    • 功能配置
    • 账号管理
    • 群组管理
    • 回调配置
  • 产品介绍
    • 消息管理
      • 单聊消息
      • 消息存储
      • 离线推送
      • 群消息
      • 消息格式
    • 账号系统
      • 登陆验证
      • 在线状态管理
    • 群相关
      • 群组系统
      • 群组管理
    • 用户资料和关系链
      • 资料管理
      • 关系链管理
  • 购买指南
    • 计费概述
    • 价格中心
  • 错误码

撤回消息

功能描述

发送方可以撤回一条已经发送成功的消息。
默认情况下,发送者只能撤回 2 分钟以内的消息,您可以按需更改消息撤回时间限制,具体操作请参见 消息撤回设置
消息的撤回同时需要接收方 UI 代码的配合:当发送方撤回一条消息后,接收方会收到消息撤回通知 onRecvMessageRevoked。通知中包含了撤回消息的 msgID,您可以根据这个 msgID 判断 UI 层是哪一条消息撤回了,然后把对应的消息气泡切换成 "消息已被撤回" 状态。
在单聊场景中,仅能撤回自己的消息;在群聊场景中,除了可以撤回自己的消息外,管理员或者群主也可以撤回其他群成员的消息。
从 IMSDK 7.4 版本开始,支持撤回包括直播群(AVChatRoom)、社群在内的所有群类型的消息。

发送方撤回消息

发送方可调用 revokeMessage (Android / iOS & Mac / Windows) 撤回一条消息。
示例代码如下:
Android
iOS & Mac
Windows
V2TIMManager.getMessageManager().revokeMessage(v2TIMMessage, new V2TIMCallback() {
@Override
public void onError(int code, String desc) {
// 撤回消息失败
}
@Override
public void onSuccess() {
// 撤回消息成功
}
});
// selectedMessage 为待撤回消息
[[V2TIMManager sharedInstance] revokeMessage:selectedMessage
succ:^{
// 撤回消息成功
} fail:^(int code, NSString *msg) {
// 撤回消息失败
}];
class Callback final : public V2TIMCallback {
public:
using SuccessCallback = std::function<void()>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

Callback() = default;
~Callback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess() override {
if (success_callback_) {
success_callback_();
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

auto callback = new Callback;
callback->SetCallback(
[=]() {
// 撤回消息成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 撤回消息失败
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->RevokeMessage(message, callback);

接收方感知消息被撤回

1. 接收方调用 addAdvancedMsgListener (Android / iOS & Mac / Windows) 设置高级消息监听。
2. 接收方在 onRecvMessageRevoked (Android / iOS & Mac / Windows) 中接收消息撤回通知。
说明:
从 7.4 版本开始,但消息被撤回后,接收方可以通过 onRecvMessageRevoked 获取消息撤回的原因和消息的撤回者。

示例代码如下:
Android
iOS & Mac
Windows
V2TIMManager.getMessageManager().addAdvancedMsgListener(new V2TIMAdvancedMsgListener() {
@Override
public void onRecvMessageRevoked(String msgID, V2TIMUserFullInfo operateUser, String reason) {
// msgList 为当前聊天界面的消息列表
for (V2TIMMessage msg : msgList) {
if (msg.getMsgID().equals(msgID)) {
// msg 即为被撤回的消息,您需要修改 UI 上相应的消息气泡的状态
}
}
}
}
// V2TIMAdvancedMsgListener
- (void)onRecvMessageRevoked:(NSString *)msgID operateUser:(V2TIMUserFullInfo *)operateUser reason:(NSString *)reason {
// 收到消息撤回通知,您需要修改 UI 上相应的消息气泡的状态
}
class AdvancedMsgListener final : public V2TIMAdvancedMsgListener {
public:
/**
* 收到新消息
*
* @param message 消息
*/
/**
* 收到消息撤回的通知
*
* @param messageID 消息唯一标识
*/
void OnRecvMessageRevoked(const V2TIMString& messageID,
const V2TIMUserFullInfo &operateUser, 
const V2TIMString &reason) override {
// msgList 为当前聊天界面的消息列表
}
// 其他成员 ...
};

// 添加高级消息的事件监听器,注意在移除监听器之前需要保持 advancedMsgListener 的生命期,以免接收不到事件回调
AdvancedMsgListener advancedMsgListener;
V2TIMManager::GetInstance()->GetMessageManager()->AddAdvancedMsgListener(&advancedMsgListener);