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

会话未读数

功能描述

会话未读数是指在一个即时通讯应用中,用户尚未阅读的消息数量。这个数量通常以小红点或者数字的方式,显示在会话列表里,提醒用户有新的未读消息需要查看。会话未读数鼓励用户及时查看和回复新消息。可以提高用户的参与度和沟通效率,防止重要信息被忽略。

效果展示

您使用本文的接口,可以实现如下图所示的效果:


接口说明

获取所有会话的未读消息总数

通常情况下,如果您想得到所有会话的未读消息总数,可以遍历会话列表得到每个会话的信息 V2TIMConversation,然后再把所有的 V2TIMConversationunreadCount 相加起来,展示在 UI 上。 但 SDK 为您提供了直接查询所有会话未读消息总数的接口 getTotalUnreadMessageCount。当会话的未读总数发生变更时,SDK 还会主动通过回调 onTotalUnreadMessageCountChanged,将最新的未读总数通知出来。
说明
1. 仅增强版 SDK 5.3.425 及以上版本,支持获取所有会话未读消息总数。
2. 仅适用于好友工作群(Work)、陌生人社交群(Public)和社群(Community),但直播群(AVChatRoom)和临时会议群(Meeting)暂不适用。群组类型详见 群组介绍
具体的操作步骤如下文所示。

获取未读总数

您可以调用 getTotalUnreadMessageCount(Android / iOS & Mac / Windows) 获取所有会话的未读消息总数,获取成功后可以使用其更新 UI。
示例代码如下:
Android
iOS & Mac
Windows
V2TIMManager.getConversationManager().getTotalUnreadMessageCount(new V2TIMValueCallback<Long>() {
@Override
public void onSuccess(Long aLong) {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
[[V2TIMManager sharedInstance] getTotalUnreadMessageCount:^(UInt64 totalCount) {
// 获取成功,totalCount 为所有会话的未读消息总数
// 更新 UI 上的未读数
} fail:^(int code, NSString *desc) {
// 获取失败
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

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

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
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 ValueCallback<uint64_t>{};
callback->SetCallback(
[=](const uint64_t& count) {
// 获取所有会话的未读总数成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 获取所有会话的未读总数失败
delete callback;
});

V2TIMManager::GetInstance()->GetConversationManager()->GetTotalUnreadMessageCount(callback);

未读总数变更通知

您可以调用 addConversationListener(Android / iOS & Mac / Windows) 添加会话监听器。添加监听器后,只需要调用过一次 getTotalUnreadMessageCount 接口,才能接收到所有会话的未读总数变更通知。
您可以在 V2TIMConversationListener 中的 onTotalUnreadMessageCountChanged(Android / iOS & Mac / Windows) 中,获取到变更后的未读总数。
示例代码如下:
Android
iOS & Mac
Windows
public void onTotalUnreadMessageCountChanged(long totalUnreadCount) {
// 收到所有会话的未读总数变更通知
Log.i("imsdk", "onTotalUnreadMessageCountChanged");
}
// 添加会话监听器
[[V2TIMManager sharedInstance] addConversationListener:self];

// 收到所有会话的未读总数变更通知
- (void)onTotalUnreadMessageCountChanged:(UInt64)totalUnreadCount {
// totalUnreadCount 为未读消息总数
}
class ConversationListener final : public V2TIMConversationListener {
public:
/**
* 会话所有会话的未读总数变更通知(5.3.425 及以上版本支持)
*
* @note
* - 未读总数会减去设置为免打扰的会话的未读数,即消息接收选项设置为
* V2TIM_NOT_RECEIVE_MESSAGE or V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE 的会话。
*/
void OnTotalUnreadMessageCountChanged(uint64_t totalUnreadCount) override {
// 收到所有会话的未读总数变更通知
}
// 其他成员函数 ...
};

// 添加会话事件监听器,注意在移除监听器之前需要保持 conversationListener 的生命期,以免接收不到事件回调
ConversationListener conversationListener;
V2TIMManager::GetInstance()->GetConversationManager()->AddConversationListener(&conversationListener);

根据过滤器获取指定会话的未读消息总数

您可以调用 getUnreadMessageCountByFilter,传入不同的过滤器 V2TIMConversationListFilter,获取指定过滤器下的会话未读消息数。
V2TIMConversationListFilter 详解如下:
属性
含义
说明
type
会话类型(填 0 代表不过滤此项)
单聊或群聊会话
conversationGroup
会话分组名称(不填写代表不过滤此项)
不是群组名称,是会话分组的名称,参考文档 会话分组
markType
会话标记类型(填 0 代表不过滤此项)
参考文档 会话标记
hasUnreadCount
会话包含未读数
true :返回包含未读数的会话;false:返回所有会话
hasGroupAtInfo
会话包含群 @ 消息
true :返回包含群 @ 消息的会话;false:返回所有会话
如果您需要监听对应的会话未读消息总数变更,可以调用 subscribeUnreadMessageCountByFilter 注册监听。当该过滤条件中的会话未读消息总数发生变更时,SDK 还会主动通过回调 onUnreadMessageCountChangedByFilter,将最新的未读总数通知出来。
说明
1. 仅增强版 SDK 7.0.3754 及以上版本,支持根据过滤条件获取部分会话的未读消息总数。
2. 仅适用于好友工作群(Work)、陌生人社交群(Public)和社群(Community),但直播群(AVChatRoom)和临时会议群(Meeting)暂不适用。群组类型详见 群组介绍
下文将列举一些过滤器拉取的典型案例。

获取仅单聊或群聊会话的未读总数

示例代码如下:
Android
iOS & Mac
Windows
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
filter.setConversationType(V2TIMConversation.V2TIM_C2C); //拉取单聊会话
// filter.setConversationType(V2TIMConversation.V2TIM_GROUP); //拉取群聊会话

V2TIMManager.getConversationManager().getUnreadMessageCountByFilter(filter, new V2TIMValueCallback<Long>() {
@Override
public void onSuccess(Long totalUnreadCount) {
tvLog.setText("getUnreadMessageCountByFilter success, totalUnreadCount:" + totalUnreadCount);
}

@Override
public void onError(int code, String desc) {
tvLog.setText("getUnreadMessageCountByFilter failed");
}
});
V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
filter.type = V2TIM_C2C; //拉取单聊会话
// filter.type = V2TIM_GROUP; //拉取群聊会话

[[V2TIMManager sharedInstance] getUnreadMessageCountByFilter:filter succ:^(UInt64 totalUnreadCount) {
[self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter success totalUnreadCount:%llu", totalUnreadCount]];
} fail:^(int code, NSString *desc) {
[self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter failed"]];
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

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

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
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_;
};

V2TIMConversationListFilter filter;
filter.type = V2TIM_C2C; // 拉取单聊会话
// filter.type = V2TIM_GROUP; // 拉取群聊会话
auto callback = new ValueCallback<uint64_t>{};
callback->SetCallback(
[=](const uint64_t& count) {
// 获取部分会话的未读总数成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 获取部分会话的未读总数失败
delete callback;
});
V2TIMManager::GetInstance()->GetConversationManager()->GetUnreadMessageCountByFilter(filter, callback);

获取指定分组会话的未读总数

示例代码如下:
Android
iOS & Mac
Windows
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
filter.setConversationGroup("conversation_group");

V2TIMManager.getConversationManager().getUnreadMessageCountByFilter(filter, new V2TIMValueCallback<Long>() {
@Override
public void onSuccess(Long totalUnreadCount) {
tvLog.setText("getUnreadMessageCountByFilter success, totalUnreadCount:" + totalUnreadCount);
}

@Override
public void onError(int code, String desc) {
tvLog.setText("getUnreadMessageCountByFilter failed");
}
});
V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
filter.conversationGroup = @"conversation_group";

[[V2TIMManager sharedInstance] getUnreadMessageCountByFilter:filter succ:^(UInt64 totalUnreadCount) {
[self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter success totalUnreadCount:%llu", totalUnreadCount]];
} fail:^(int code, NSString *desc) {
[self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter failed"]];
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

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

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
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_;
};

V2TIMConversationListFilter filter;
filter.conversationGroup = "conversation_group";
auto callback = new ValueCallback<uint64_t>{};
callback->SetCallback(
[=](const uint64_t& count) {
// 获取部分会话的未读总数成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 获取部分会话的未读总数失败
delete callback;
});
V2TIMManager::GetInstance()->GetConversationManager()->GetUnreadMessageCountByFilter(filter, callback);

获取指定标记会话的未读总数

示例代码如下:
Android
iOS & Mac
Windows
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
filter.setMarkType(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_STAR);

V2TIMManager.getConversationManager().getUnreadMessageCountByFilter(filter, new V2TIMValueCallback<Long>() {
@Override
public void onSuccess(Long totalUnreadCount) {
tvLog.setText("getUnreadMessageCountByFilter success, totalUnreadCount:" + totalUnreadCount);
}

@Override
public void onError(int code, String desc) {
tvLog.setText("getUnreadMessageCountByFilter failed");
}
});
V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
filter.markType = V2TIM_CONVERSATION_MARK_TYPE_STAR;

[[V2TIMManager sharedInstance] getUnreadMessageCountByFilter:filter succ:^(UInt64 totalUnreadCount) {
[self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter success totalUnreadCount:%llu", totalUnreadCount]];
} fail:^(int code, NSString *desc) {
[self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter failed"]];
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

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

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
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_;
};

V2TIMConversationListFilter filter;
filter.markType = V2TIM_CONVERSATION_MARK_TYPE_STAR;
auto callback = new ValueCallback<uint64_t>{};
callback->SetCallback(
[=](const uint64_t& count) {
// 获取部分会话的未读总数成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 获取部分会话的未读总数失败
delete callback;
});
V2TIMManager::GetInstance()->GetConversationManager()->GetUnreadMessageCountByFilter(filter, callback);

获取含有未读数会话的未读总数

示例代码如下:
Android
iOS & Mac
Windows
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
filter.setHasUnreadCount(true);

V2TIMManager.getConversationManager().getUnreadMessageCountByFilter(filter, new V2TIMValueCallback<Long>() {
@Override
public void onSuccess(Long totalUnreadCount) {
tvLog.setText("getUnreadMessageCountByFilter success, totalUnreadCount:" + totalUnreadCount);
}

@Override
public void onError(int code, String desc) {
tvLog.setText("getUnreadMessageCountByFilter failed");
}
});
V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
filter.hasUnreadCount = YES;

[[V2TIMManager sharedInstance] getUnreadMessageCountByFilter:filter succ:^(UInt64 totalUnreadCount) {
[self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter success totalUnreadCount:%llu", totalUnreadCount]];
} fail:^(int code, NSString *desc) {
[self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter failed"]];
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

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

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
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_;
};

V2TIMConversationListFilter filter;
filter.hasUnreadCount = true;
auto callback = new ValueCallback<uint64_t>{};
callback->SetCallback(
[=](const uint64_t& count) {
// 获取部分会话的未读总数成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 获取部分会话的未读总数失败
delete callback;
});
V2TIMManager::GetInstance()->GetConversationManager()->GetUnreadMessageCountByFilter(filter, callback);

获取含有群 @ 消息会话的未读数

示例代码如下:
Android
iOS & Mac
Windows
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
filter.setHasGroupAtInfo(true);

V2TIMManager.getConversationManager().getUnreadMessageCountByFilter(filter, new V2TIMValueCallback<Long>() {
@Override
public void onSuccess(Long totalUnreadCount) {
tvLog.setText("getUnreadMessageCountByFilter success, totalUnreadCount:" + totalUnreadCount);
}

@Override
public void onError(int code, String desc) {
tvLog.setText("getUnreadMessageCountByFilter failed");
}
});
V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
filter.hasGroupAtInfo = YES;

[[V2TIMManager sharedInstance] getUnreadMessageCountByFilter:filter succ:^(UInt64 totalUnreadCount) {
[self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter success totalUnreadCount:%llu", totalUnreadCount]];
} fail:^(int code, NSString *desc) {
[self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter failed"]];
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

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

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
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_;
};

V2TIMConversationListFilter filter;
filter.hasGroupAtInfo = true;
auto callback = new ValueCallback<uint64_t>{};
callback->SetCallback(
[=](const uint64_t& count) {
// 获取部分会话的未读总数成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 获取部分会话的未读总数失败
delete callback;
});
V2TIMManager::GetInstance()->GetConversationManager()->GetUnreadMessageCountByFilter(filter, callback);

未读消息总数变更通知

注册监听部分会话的未读消息总数变更

您可以调用 addConversationListener(Android / iOS & Mac / Windows) 添加会话监听器。
添加后,需要调用 subscribeUnreadMessageCountByFilter(Android / iOS & Mac / Windows) 注册监听指定过滤条件下的未读消息总数变更。
注册后,您可以在onUnreadMessageCountChangedByFilter(Android / iOS & Mac / Windows) 中,获取到变更后的未读总数。
SDK 支持注册监听多个、不同过滤条件的未读总数变更。调用接口 subscribeUnreadMessageCountByFilter 时传入的 filter,会在 onUnreadMessageCountChangedByFilter 通知中返回。该 filter 携带了 conversationTypeconversationGroupmarkType 三个字段,您可以通过判断这三字段区分出不同的过滤条件。
示例代码如下:
Android
iOS & Mac
Windows
// 添加会话监听器
V2TIMManager.getConversationManager().addConversationListener(conversationListener);

// 注册监听指定过滤条件下的未读消息总数变更
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
filter.setConversationType(V2TIMConversation.V2TIM_GROUP);
filter.setConversationGroup("conversation_group");
filter.setMarkType(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_STAR);
V2TIMManager.getConversationManager().subscribeUnreadMessageCountByFilter(filter);

// 指定过滤条件下的未读消息总数变更通知
public void onUnreadMessageCountChangedByFilter(V2TIMConversationListFilter filter, long totalUnreadCount) {
// filter 是过滤条件,totalUnreadCount 是未读消息总数
Log.i(TAG, "onUnreadMessageCountChangedByFilter:" + totalUnreadCount + "\n");
}
// 添加会话监听器
[[V2TIMManager sharedInstance] addConversationListener:self];

// 注册监听指定过滤条件下的未读消息总数变更
V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
filter.type = V2TIM_GROUP;
filter.conversationGroup = @"conversation_group";
filter.markType = V2TIM_CONVERSATION_MARK_TYPE_STAR;
[[V2TIMManager sharedInstance] subscribeUnreadMessageCountByFilter:filter];

// 指定过滤条件下的未读消息总数变更通知
- (void)onUnreadMessageCountChangedByFilter:(V2TIMConversationListFilter *)filter totalUnreadCount:(UInt64)totalUnreadCount {
// filter 是过滤条件,totalUnreadCount 是未读消息总数
}
class ConversationListener final : public V2TIMConversationListener {
public:
// 指定过滤条件下的未读消息总数变更通知
void OnUnreadMessageCountChangedByFilter(const V2TIMConversationListFilter &filter, uint64_t totalUnreadCount) override {
// filter 是过滤条件,totalUnreadCount 是未读消息总数
}
// 其他成员函数 ...
};

// 添加会话事件监听器,注意在移除监听器之前需要保持 conversationListener 的生命期,以免接收不到事件回调
ConversationListener conversationListener;
V2TIMManager::GetInstance()->GetConversationManager()->AddConversationListener(&conversationListener);

// 注册监听指定过滤条件下的未读消息总数变更
V2TIMConversationListFilter filter;
filter.type = V2TIM_GROUP;
filter.conversationGroup = "conversation_group";
filter.markType = V2TIM_CONVERSATION_MARK_TYPE_STAR;
V2TIMManager::GetInstance()->GetConversationManager()->SubscribeUnreadMessageCountByFilter(filter);

取消监听部分会话的未读消息总数变更

您可以调用 unsubscribeUnreadMessageCountByFilter(Android / iOS & Mac / Windows) 接口,取消监听指定过滤条件下的未读消息总数变更。
示例代码如下:
Android
iOS & Mac
Windows
// 取消监听指定过滤条件下的未读消息总数变更
V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
filter.setConversationType(V2TIMConversation.V2TIM_GROUP);
filter.setConversationGroup("conversation_group");
filter.setMarkType(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_STAR);
V2TIMManager.getConversationManager().unsubscribeUnreadMessageCountByFilter(filter);
// 取消监听指定过滤条件下的未读消息总数变更
V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
filter.type = V2TIM_GROUP;
filter.conversationGroup = @"conversation_group";
filter.markType = V2TIM_CONVERSATION_MARK_TYPE_STAR;
[[V2TIMManager sharedInstance] unsubscribeUnreadMessageCountByFilter:filter];
// 取消监听指定过滤条件下的未读消息总数变更
V2TIMConversationListFilter filter;
filter.type = V2TIM_GROUP;
filter.conversationGroup = "conversation_group";
filter.markType = V2TIM_CONVERSATION_MARK_TYPE_STAR;
V2TIMManager::GetInstance()->GetConversationManager()->UnsubscribeUnreadMessageCountByFilter(filter);

清理会话未读消息数

用户点击进入会话后,再退回到会话列表,需要清理未读消息数。当未读数被清零,会话列表的小红点或数字角标通常需要随之消失。
您可以调用 cleanConversationUnreadMessageCountAndroid / iOS & Mac / Windows)来清理指定会话未读消息数,通过传入特定格式的参数区分不同种类的会话,具体的操作步骤如下文所示。
说明:
清理指定会话未读消息数功能仅增强版 SDK 7.1.3925 及以上版本支持。

清理指定单聊会话的未读数

您可以通过传入带有 "c2c_" 前缀的 conversationID 来清理指定单聊会话未读消息数,同时还可以通过传入 cleanTimestamp 来清理指定时间戳及其之前的未读消息数。如果传入的 cleanTimestamp 为 0,则将指定单聊会话的未读数清 0。
示例代码如下:
Android
iOS & Mac
Windows
String conversationID = "c2c_userID";
V2TIMManager.getConversationManager().cleanConversationUnreadMessageCount(conversationID, 123456, 0, new V2TIMCallback() {
@Override
public void onSuccess() {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
[[V2TIMManager sharedInstance] cleanConversationUnreadMessageCount:@"c2c_userID"
cleanTimestamp:123456
cleanSequence:0
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_;
};

V2TIMString conversationID = u8"c2c_userID";

auto callback = new Callback;
callback->SetCallback(
[=]() {
// 清理指定单聊会话未读数成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 清理指定单聊会话未读数失败
delete callback;
});

V2TIMManager::GetInstance()->GetConversationManager()->CleanConversationUnreadMessageCount(conversationID, 123456, 0, callback);
当本端调用 cleanConversationUnreadMessageCount 成功后,如果调用者事先调用 addConversationListener 添加了会话监听器,会收到 onConversationChanged 回调,该回调中携带了对应会话的最新未读消息数,可以在此回调中更新 UI。
示例代码如下:
Android
iOS & Mac
Windows
public void onConversationChanged(List<V2TIMConversation> conversationList) {
// 调用者收到会话信息变更通知
Log.i("imsdk", "onConversationChanged");
}
// 添加会话监听器
[[V2TIMManager sharedInstance] addConversationListener:self];

// 调用者收到会话信息变更通知
- (void)onConversationChanged:(NSArray<V2TIMConversation*> *)conversationList {
// 根据 conversationList 中的 V2TIMConversation 更新对应 UI
}
class ConversationListener final : public V2TIMConversationListener {
public:
/**
* 某些会话的关键信息发生变化(未读计数发生变化、最后一条消息被更新等等),可以根据会话的
* lastMessage -> timestamp 重新对会话列表做排序
*
* @param conversationList 会话列表
*/
void OnConversationChanged(const V2TIMConversationVector& conversationList) override {}
// 其他成员 ...
};

// 添加会话事件监听器,注意在移除监听器之前需要保持 conversationListener 的生命期,以免接收不到事件回调
ConversationListener conversationListener;
V2TIMManager::GetInstance()->GetConversationManager()->AddConversationListener(&conversationListener);

清空所有单聊会话的未读数

您可以传入 "c2c" 作为 conversationID,表示将所有单聊会话的未读数全部清 0,请注意此时 cleanTimestamp 将不再生效。
示例代码如下:
Android
iOS & Mac
Windows
String conversationID = "c2c";
V2TIMManager.getConversationManager().cleanConversationUnreadMessageCount(conversationID, 0, 0, new V2TIMCallback() {
@Override
public void onSuccess() {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
[[V2TIMManager sharedInstance] cleanConversationUnreadMessageCount:@"c2c"
cleanTimestamp:0
cleanSequence:0
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_;
};

V2TIMString conversationID = u8"c2c";

auto callback = new Callback;
callback->SetCallback(
[=]() {
// 清空所有单聊会话未读消息数成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 清空所有单聊会话未读消息数失败
delete callback;
});

V2TIMManager::GetInstance()->GetConversationManager()->CleanConversationUnreadMessageCount(conversationID, 0, 0, callback);
当本端调用 cleanConversationUnreadMessageCount 成功后,如果调用者事先调用 addConversationListener 添加了会话监听器,会收到 onConversationChanged 回调,该回调中携带了对应会话的最新未读消息数,可以在此回调中更新 UI。
示例代码如下:
Android
iOS & Mac
Windows
public void onConversationChanged(List<V2TIMConversation> conversationList) {
// 调用者收到会话信息变更通知
Log.i("imsdk", "onConversationChanged");
}
// 添加会话监听器
[[V2TIMManager sharedInstance] addConversationListener:self];

// 调用者收到会话信息变更通知
- (void)onConversationChanged:(NSArray<V2TIMConversation*> *)conversationList {
// 根据 conversationList 中的 V2TIMConversation 更新对应 UI,例如清除掉单聊会话 cell 小红点
}
class ConversationListener final : public V2TIMConversationListener {
public:
/**
* 某些会话的关键信息发生变化(未读计数发生变化、最后一条消息被更新等等),可以根据会话的
* lastMessage -> timestamp 重新对会话列表做排序
*
* @param conversationList 会话列表
*/
void OnConversationChanged(const V2TIMConversationVector& conversationList) override {}
// 其他成员 ...
};

// 添加会话事件监听器,注意在移除监听器之前需要保持 conversationListener 的生命期,以免接收不到事件回调
ConversationListener conversationListener;
V2TIMManager::GetInstance()->GetConversationManager()->AddConversationListener(&conversationListener);

清理指定群聊会话的未读数

您可以通过传入带有 "group_" 前缀的 conversationID 来清理指定群聊会话未读消息数,同时还可以通过传入 cleanSequence 来清理指定 sequence 及其之前的未读消息数。如果传入的 cleanSequence 为 0,则将指定群聊会话的未读数清 0。
示例代码如下:
Android
iOS & Mac
Windows
String conversationID = "group_groupID";
V2TIMManager.getConversationManager().cleanConversationUnreadMessageCount(conversationID, 0, 123, new V2TIMCallback() {
@Override
public void onSuccess() {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
[[V2TIMManager sharedInstance] cleanConversationUnreadMessageCount:@"group_groupID"
cleanTimestamp:0
cleanSequence:123
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_;
};

V2TIMString conversationID = u8"group_groupID";

auto callback = new Callback;
callback->SetCallback(
[=]() {
// 清理指定群聊会话未读消息数成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 清理指定群聊会话未读消息数失败
delete callback;
});

V2TIMManager::GetInstance()->GetConversationManager()->CleanConversationUnreadMessageCount(conversationID, 0, 123, callback);
当 cleanConversationUnreadMessageCount 调用成功后,如果调用者事先调用 addConversationListener 添加了会话监听器,会收到 onConversationChanged 回调,该回调中携带了对应会话的最新未读消息数,可以在此回调中更新 UI。
示例代码如下:
Android
iOS & Mac
Windows
public void onConversationChanged(List<V2TIMConversation> conversationList) {
// 调用者收到会话信息变更通知
Log.i("imsdk", "onConversationChanged");
}
// 添加会话监听器
[[V2TIMManager sharedInstance] addConversationListener:self];

// 调用者收到会话信息变更通知
- (void)onConversationChanged:(NSArray<V2TIMConversation*> *)conversationList {
// 根据 conversationList 中的 V2TIMConversation 更新对应 UI
}
class ConversationListener final : public V2TIMConversationListener {
public:
void OnConversationChanged(const V2TIMConversationVector& conversationList) override {}
// 调用者收到会话信息变更通知
};

// 添加会话事件监听器,注意在移除监听器之前需要保持 conversationListener 的生命期,以免接收不到事件回调
ConversationListener conversationListener;
V2TIMManager::GetInstance()->GetConversationManager()->AddConversationListener(&conversationListener);
```

### 清空所有群聊会话的未读数

您可以传入 "group" 作为 conversationID,表示将所有群聊会话的未读数全部清 0,请注意此时 cleanSequence 将不再生效。

【Android】

```java
String conversationID = "group";
V2TIMManager.getConversationManager().cleanConversationUnreadMessageCount(conversationID, 0, 0, new V2TIMCallback() {
@Override
public void onSuccess() {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});

清空所有群聊会话的未读数

您可以传入 "group" 作为 conversationID,表示将所有群聊会话的未读数全部清 0,请注意此时 cleanSequence 将不再生效。
Android
iOS & Mac
Windows
String conversationID = "group";
V2TIMManager.getConversationManager().cleanConversationUnreadMessageCount(conversationID, 0, 0, new V2TIMCallback() {
@Override
public void onSuccess() {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
[[V2TIMManager sharedInstance] cleanConversationUnreadMessageCount:@"group"
cleanTimestamp:0
cleanSequence:0
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_;
};

V2TIMString conversationID = u8"group";

auto callback = new Callback;
callback->SetCallback(
[=]() {
// 清空所有群聊会话未读消息数成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 清空所有群聊会话未读消息数失败
delete callback;
});

V2TIMManager::GetInstance()->GetConversationManager()->CleanConversationUnreadMessageCount(conversationID, 0, 0, callback);
当 cleanConversationUnreadMessageCount 调用成功后,如果调用者事先调用 addConversationListener 添加了会话监听器,会收到 onConversationChanged 回调,该回调中携带了对应会话的最新未读消息数,可以在此回调中更新 UI。
示例代码如下:
Android
iOS & Mac
Windows
public void onConversationChanged(List<V2TIMConversation> conversationList) {
// 调用者收到会话信息变更通知
Log.i("imsdk", "onConversationChanged");
}
// 添加会话监听器
[[V2TIMManager sharedInstance] addConversationListener:self];

// 调用者收到会话信息变更通知
- (void)onConversationChanged:(NSArray<V2TIMConversation*> *)conversationList {
// 根据 conversationList 中的 V2TIMConversation 更新对应 UI,例如清除掉群聊会话 cell 小红点
}
class ConversationListener final : public V2TIMConversationListener {
public:
void OnConversationChanged(const V2TIMConversationVector& conversationList) override {}
// 调用者收到会话信息变更通知
};

// 添加会话事件监听器,注意在移除监听器之前需要保持 conversationListener 的生命期,以免接收不到事件回调
ConversationListener conversationListener;
V2TIMManager::GetInstance()->GetConversationManager()->AddConversationListener(&conversationListener);

清空所有会话的未读数

您可以传入空字符串 "" 作为 conversationID,表示将所有会话的未读消息数全部清 0,请注意此时 cleanTimestamp 和 cleanSequence 都不再生效。
示例代码如下:
Android
iOS & Mac
Windows
String conversationID = "";
V2TIMManager.getConversationManager().cleanConversationUnreadMessageCount(conversationID, 0, 0, new V2TIMCallback() {
@Override
public void onSuccess() {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
[[V2TIMManager sharedInstance] cleanConversationUnreadMessageCount:@""
cleanTimestamp:0
cleanSequence:0
succ:^{
// 清空所有会话未读消息数成功
} fail:^(int code, NSString *desc) {
// 清空所有会话未读消息数失败
}];
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_;
};

V2TIMString conversationID = u8"";

auto callback = new Callback;
callback->SetCallback(
[=]() {
// 清空所有会话未读消息数成功
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// 清空所有会话未读消息数失败
delete callback;
});

V2TIMManager::GetInstance()->GetConversationManager()->CleanConversationUnreadMessageCount(conversationID, 0, 0, callback);
当 cleanConversationUnreadMessageCount 调用成功后,如果调用者事先调用 addConversationListener 添加了会话监听器,会收到 onConversationChanged 回调,该回调中携带了对应会话的最新未读消息数,可以在此回调中更新 UI。
示例代码如下:
Android
iOS & Mac
Windows
public void onConversationChanged(List<V2TIMConversation> conversationList) {
// 收到会话信息变更通知
Log.i("imsdk", "onConversationChanged");
}
// 添加会话监听器
[[V2TIMManager sharedInstance] addConversationListener:self];

// 调用者收到会话信息变更通知
- (void)onConversationChanged:(NSArray<V2TIMConversation*> *)conversationList {
// 更新 UI,例如清除掉会话列表底部 tab 小红点
}
class ConversationListener final : public V2TIMConversationListener {
public:
void OnConversationChanged(const V2TIMConversationVector& conversationList) override {}
// 调用者收到会话信息变更通知
};

// 添加会话事件监听器,注意在移除监听器之前需要保持 conversationListener 的生命期,以免接收不到事件回调
ConversationListener conversationListener;
V2TIMManager::GetInstance()->GetConversationManager()->AddConversationListener(&conversationListener);

发送不计入会话未读数的消息

正常情况下,无论是发送单聊消息还是群聊消息,都会计入未读消息数(通过会话对象 V2TIMConversationunreadCount 接口,可以拿到一个会话的未读消息数)。 当您希望发送一些不计入未读计数的消息,例如提示类或者控制类的消息,可以在调用 sendMessage 时:
对于 Android 而言,调用 setExcludedFromUnreadCount 方法,设置为 true
对于 iOS/Windows 而言,设置消息对象的 isExcludedFromUnreadCountYES/true
发送消息 sendMessage 的使用参考:发送消息
说明
setExcludedFromUnreadCountisExcludedFromUnreadCount 参数仅增强版 5.3.425 及以上版本支持。
示例代码如下:
Android
iOS & Mac
Windows
// 创建消息对象
V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createTextMessage(content);
// 设置不更新会话 lastMessage
v2TIMMessage.setExcludedFromUnreadCount(true);

// 发送消息
V2TIMManager.getMessageManager().sendMessage(v2TIMMessage, "userID", null, V2TIMMessage.V2TIM_PRIORITY_DEFAULT, false, null, new V2TIMSendCallback<V2TIMMessage>() {
@Override
public void onSuccess(V2TIMMessage v2TIMMessage) {
Log.i("imsdk", "success");
}

@Override
public void onProgress(int progress) {
Log.i("imsdk", "progress:" + progress);
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
// 创建消息对象
V2TIMMessage *message = [[V2TIMManager sharedInstance] createTextMessage:@"这是一个信令消息"];

// 设置不计入未读消息总数的标记
message.isExcludedFromUnreadCount = YES;

// 发送消息
[[V2TIMManager sharedInstance] sendMessage:msg receiver:@"userA" groupID:nil
priority:V2TIM_PRIORITY_DEFAULT onlineUserOnly:YES offlinePushInfo:nil progress:^(uint32_t progress) {
} succ:^{
// 消息发送成功
} fail:^(int code, NSString *msg) {
// 消息发送失败
}];
class SendCallback final : public V2TIMSendCallback {
public:
using SuccessCallback = std::function<void(const V2TIMMessage&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;
using ProgressCallback = std::function<void(uint32_t)>;

SendCallback() = default;
~SendCallback() override = default;

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

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