Android&iOS&Windows&Mac

最近更新时间:2024-05-11 11:18:32

我的收藏

功能描述

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

效果展示

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


接口说明

未读数类型
获取未读数
未读数变化通知
清理未读数
总未读数
分组会话的未读总数
单聊/群聊分组会话的未读总数
指定分组会话的未读总数
已读即可
含有未读数会话分组的未读总数
已读即可
含有群@消息会话分组的未读总数
已读即可
指定标记会话分组的未读总数
已读即可
单个单聊会话的未读数
单个群聊会话的未读数

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

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

获取所有会话的未读总数

您可以调用 getTotalUnreadMessageCountAndroid / 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);

所有会话的未读总数变更通知

您可以调用 addConversationListenerAndroid / iOS & Mac / Windows)添加会话监听器。添加监听器后,只需要调用过一次 getTotalUnreadMessageCount 接口,才能接收到所有会话的未读总数变更通知。
您可以在 V2TIMConversationListener 中的 onTotalUnreadMessageCountChangedAndroid / 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);

根据过滤条件获取部分会话的未读消息总数

IM SDK 为您提供了根据过滤条件查询部分会话未读消息总数的接口 getUnreadMessageCountByFilter。 如果您需要监听指定过滤条件下的会话未读消息总数变更,可以调用 subscribeUnreadMessageCountByFilter 注册监听,当该过滤条件下的会话未读消息总数发生变更时,SDK 还会主动通过回调 onUnreadMessageCountChangedByFilter,将最新的未读总数通知出来。
说明
1. 仅增强版 7.0.3754 及以上版本,支持根据过滤条件获取部分会话的未读消息总数。
2. 仅适用于好友工作群(Work)、陌生人社交群(Public)和社群(Community),但直播群(AVChatRoom)和临时会议群(Meeting)暂不适用。群组类型详见 群组介绍
您可以调用 getUnreadMessageCountByFilterAndroid / iOS & Mac / Windows )获取部分会话的未读消息总数,获取成功后可以使用其更新 UI。其中过滤条件 V2TIMConversationListFilter 详解如下:
属性
含义
说明
type
会话类型(填 0 代表不过滤此项)
C2C 或者群组会话
conversationGroup
会话分组名称(不填写代表不过滤此项)
不是群组名称,是会话分组的名称,参见文档 会话分组
markType
会话标记类型(填 0 代表不过滤此项)
参考文档 会话标记
hasUnreadCount
会话包含未读数
true :返回包含未读数的会话;
false:返回所有会话
hasGroupAtInfo
会话包含群 @ 消息
true :返回包含群 @ 消息的会话;
false:返回所有会话

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

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);

未读消息总数变更

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

您可以调用 addConversationListenerAndroid / iOS & Mac / Windows)添加会话监听器。添加监听器后,需要您调用 subscribeUnreadMessageCountByFilterAndroid / iOS & Mac / Windows)接口,注册监听指定过滤条件下的未读消息总数变更。
您可以在 V2TIMConversationListener 中的 onUnreadMessageCountChangedByFilterAndroid / iOS & Mac / Windows)中,获取到变更后的未读总数。
您可以注册监听多个不同过滤条件下的未读总数变更,onUnreadMessageCountChangedByFilter 回调的 filter 参数就是调用 subscribeUnreadMessageCountByFilter 时指定的 filter,该 filter 携带了 conversationType、conversationGroup 和 markType 三个字段,通过判断这三字段是不是都相同,来区分出不同的过滤条件。
示例代码如下:
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);

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

您可以调用 unsubscribeUnreadMessageCountByFilterAndroid / 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);

清理会话未读消息数

用户点击进入会话后,再退回到会话列表,需要清理未读消息数。若未读数被清 0 ,则会话列表的小红点或数字角标需要随之消失。 您可以调用 cleanConversationUnreadMessageCountAndroid / iOS & Mac / Windows)来清理指定会话未读消息数,通过传入特定格式的参数可以分别完成对指定单聊会话全部单聊会话指定群聊会话全部群聊会话以及全部会话未读消息数的清理,具体的操作步骤如下文所示。
说明
清理会话未读消息数功能仅增强版 7.1.3925 及以上版本支持。
接口说明如下:
Android
iOS & Mac
Windows
方法原型:
// V2TIMConversationManager
public abstract void cleanConversationUnreadMessageCount(String conversationID, long cleanTimestamp,
long cleanSequence, V2TIMCallback callback);
参数说明:
参数
含义
单聊有效
群聊有效
说明
conversationID
会话唯一 ID
YES
YES
C2C 单聊组成方式为: String.format("c2c_%s", "userID");群聊组成方式为: String.format("group_%s", "groupID")。
cleanTimestamp
清理时间戳,单位为秒
YES
NO
指定清理哪一个 timestamp 之前的未读消息计数;当传入为 0 时,对应会话所有的未读消息将被清理,会话的未读数会清 0。
cleanSequence
清理 sequence
NO
YES
指定清理哪一个 sequence 之前的未读消息计数;当传入为 0 时,对应会话所有的未读消息将被清理,会话的未读数会清 0。
callback
清理会话未读数结果回调
YES
YES
接口调用成功与否的回调。
方法原型:
// V2TIMManager+Conversation.h
- (void)cleanConversationUnreadMessageCount:(NSString *)conversationID
cleanTimestamp:(uint64_t)cleanTimestamp
cleanSequence:(uint64_t)cleanSequence
succ:(V2TIMSucc)succ
fail:(V2TIMFail)fail;
参数说明:
参数
含义
单聊有效
群聊有效
说明
conversationID
会话唯一 ID
YES
YES
C2C 单聊组成方式:[NSString stringWithFormat:@"c2c_%@",userID];群聊组成方式为 [NSString stringWithFormat:@"group_%@",groupID]。
cleanTimestamp
清理时间戳
YES
NO
指定清理哪一个 timestamp 之前的未读消息计数;当传入为 0 时,对应会话所有的未读消息将被清理,会话的未读数会清 0。
cleanSequence
清理 sequence
NO
YES
指定清理哪一个 sequence 之前的未读消息计数;当传入为 0 时,对应会话所有的未读消息将被清理,会话的未读数会清 0。
succ
清理会话未读数结果成功回调
YES
YES
——
fail
消息发送失败回调
YES
YES
回调失败错误码、错误描述。

方法原型:
// V2TIMConversationManager
virtual void CleanConversationUnreadMessageCount(
const V2TIMString& conversationID,
uint64_t cleanTimestamp,
uint64_t cleanSequence,
V2TIMCallback* callback);
参数说明:
参数
含义
单聊有效
群聊有效
说明
conversationID
会话唯一 ID
YES
YES
C2C 单聊组成方式为: "c2c_userID";群聊组成方式为: "group_groupID"
cleanTimestamp
清理时间戳
YES
NO
指定清理哪一个 timestamp 之前的未读消息计数;当传入为 0 时,对应会话所有的未读消息将被清理,会话的未读数会清 0。
cleanSequence
清理 sequence
NO
YES
指定清理哪一个 sequence 之前的未读消息计数;当传入为 0 时,对应会话所有的未读消息将被清理,会话的未读数会清 0。
callback
清理会话未读数结果回调
YES
YES
接口调用成功与否的回调。

说明
当您想清理所有单聊会话的未读消息计数,conversationID 请传入 "c2c",即不指定具体的 userID;
当您想清理所有群聊会话的未读消息计数,conversationID 请传入 "group",即不指定具体的 groupID;
当您想清理所有会话的未读消息计数,conversationID 请传入 "";
该接口调用成功后,SDK 会通过 onConversationChanged 回调将对应会话的最新未读数通知给您。

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

您可以通过传入带有 "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
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);
}
}
void OnProgress(uint32_t progress) override {
if (progress_callback_) {
progress_callback_(progress);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
ProgressCallback progress_callback_;
};

// 创建消息对象
V2TIMMessage message = V2TIMManager::GetInstance()->GetMessageManager()->CreateTextMessage(u8"content");
// 设置不更新会话 lastMessage
message.isExcludedFromUnreadCount = true;

auto callback = new SendCallback{};
callback->SetCallback([=](const V2TIMMessage& message) { delete callback; },
[=](int error_code, const V2TIMString& error_message) { delete callback; },
[=](uint32_t progress) {});

V2TIMManager::GetInstance()->GetMessageManager()->SendMessage(
message, u8"userID", {}, V2TIMMessagePriority::V2TIM_PRIORITY_NORMAL, false, {}, callback);