一、添加监听器
接收方调用 addAdvancedMsgListener (点击查看详情) 添加高级消息监听器。一般建议在比较靠前的时间点调用,例如聊天消息界面初始化后,确保 App 能及时收到消息。
示例代码如下:
// 创建消息监听器 V2TimAdvancedMsgListener listener = V2TimAdvancedMsgListener( onRecvC2CReadReceipt: (List<V2TimMessageReceipt> receiptList) { //单聊已读回调 }, onRecvMessageModified: (V2TimMessage message) { // msg 为被修改之后的消息对象 }, onRecvMessageReadReceipts: (List<V2TimMessageReceipt> receiptList) { //群聊已读回调 receiptList.forEach((element) { element.groupID; // 群id element.msgID; // 已读回执消息 ID element.readCount; // 群消息最新已读数 element.unreadCount; // 群消息最新未读数 element.userID; // C2C 消息对方 ID }); }, onRecvMessageRevoked: (String messageid) { // 在本地维护的消息中处理被对方撤回的消息 }, onRecvNewMessage: (V2TimMessage message) async { // 处理文本消息 if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT) { message.textElem?.text; } // 使用自定义消息 if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_CUSTOM) { message.customElem?.data; message.customElem?.desc; message.customElem?.extension; } // 使用图片消息 if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_IMAGE) { message.imageElem ?.path; // 图片上传时的路径,消息发送者才会有这个字段,消息发送者可用这个字段将图片预先上屏,优化上屏体验。 message.imageElem?.imageList?.forEach((element) { // 遍历大图、原图、缩略图 // 解析图片属性 element?.height; element?.localUrl; element?.size; element?.type; // 大图 缩略图 原图 element?.url; element?.uuid; element?.width; }); } // 处理视频消息 if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_VIDEO) { // 解析视频消息属性,封面、播放地址、宽高、大小等。 message.videoElem?.UUID; message.videoElem?.duration; message.videoElem?.localSnapshotUrl; message.videoElem?.localVideoUrl; message.videoElem?.snapshotHeight; message.videoElem?.snapshotPath; // … } // 处理音频消息 if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_SOUND) { // 解析语音消息 播放地址,本地地址,大小,时长等。 message.soundElem?.UUID; message.soundElem?.dataSize; message.soundElem?.duration; message.soundElem?.localUrl; message.soundElem?.url; // … } // 处理文件消息 if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_FILE) { // 解析文件消息 文件名、文件大小、url等 message.fileElem?.UUID; message.fileElem?.fileName; message.fileElem?.fileSize; message.fileElem?.localUrl; message.fileElem?.path; message.fileElem?.url; } // 处理位置消息 if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_LOCATION) { // 解析地理位置消息,经纬度、描述等 message.locationElem?.desc; message.locationElem?.latitude; message.locationElem?.longitude; } // 处理表情消息 if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_FACE) { message.faceElem?.data; message.faceElem?.index; } // 处理群组tips文本消息 if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS) { message.groupTipsElem?.groupID; // 所属群组 message.groupTipsElem?.type; // 群Tips类型 message.groupTipsElem?.opMember; // 操作人资料 message.groupTipsElem?.memberList; // 被操作人资料 message.groupTipsElem?.groupChangeInfoList; // 群信息变更详情 message.groupTipsElem?.memberChangeInfoList; // 群成员变更信息 message.groupTipsElem?.memberCount; // 当前群在线人数 } // 处理合并消息消息 if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_MERGER) { message.mergerElem?.abstractList; message.mergerElem?.isLayersOverLimit; message.mergerElem?.title; V2TimValueCallback<List<V2TimMessage>> download = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .downloadMergerMessage( msgID: message.msgID!, ); if (download.code == 0) { List<V2TimMessage>? messageList = download.data; } } if (message.textElem?.nextElem != null) { //通过第一个 Elem 对象的 nextElem 方法获取下一个 Elem 对象,如果下一个 Elem 对象存在,会返回 Elem 对象实例,如果不存在,会返回 null。 } }, onSendMessageProgress: (V2TimMessage message, int progress) { //文件上传进度回调 }, ); // 添加高级消息的事件监听器 TencentImSDKPlugin.v2TIMManager .getMessageManager() .addAdvancedMsgListener(listener: listener);
二、移除监听器
如果想停止接收消息,接收方可调用 removeAdvancedMsgListener(点击查看详情)移除高级消息监听器。
示例代码如下:
// 创建listenerV2TimAdvancedMsgListener listener = V2TimAdvancedMsgListener( onRecvC2CReadReceipt: (List<V2TimMessageReceipt> receiptList) {}, onRecvMessageModified: (V2TimMessage message) {}, onRecvMessageReadReceipts: (List<V2TimMessageReceipt> receiptList) {}, onRecvMessageRevoked: (String messageid) {}, onRecvNewMessage: (V2TimMessage message) {}, onSendMessageProgress: (V2TimMessage message, int progress) {}, );// 注册listener TencentImSDKPlugin.v2TIMManager .getMessageManager() .addAdvancedMsgListener(listener: listener);// 移除listenerTencentImSDKPlugin.v2TIMManager.getMessageManager().removeAdvancedMsgListener(listener: listener);
三、接收文本消息
接收方使用高级消息监听器接收单聊、群聊文本消息,需要以下几步:
1. 调用 addAdvancedMsgListener 设置事件监听器。
2. 监听 onRecvNewMessage(点击查看详情)回调,在其中接收文本消息。
3. 希望停止接收消息,调用 removeAdvancedMsgListener 移除监听。该步骤不是必须的,客户可以按照业务需求调用。
代码示例如下:
V2TimAdvancedMsgListener listener = V2TimAdvancedMsgListener( onRecvC2CReadReceipt: (List<V2TimMessageReceipt> receiptList) {}, onRecvMessageModified: (V2TimMessage message) {}, onRecvMessageReadReceipts: (List<V2TimMessageReceipt> receiptList) {}, onRecvMessageRevoked: (String messageid) {}, onRecvNewMessage: (V2TimMessage message) { // 处理文本消息 if(message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT){ String text = message.textElem.text; } }, onSendMessageProgress: (V2TimMessage message, int progress) {}, ); TencentImSDKPlugin.v2TIMManager .getMessageManager() .addAdvancedMsgListener(listener: listener);
四、接收自定义消息
接收方使用高级消息监听器接收单聊、群聊自定义消息,需要以下几步:
1. 调用 addAdvancedMsgListener 设置事件监听器。
2. 监听 onRecvNewMessage(点击查看详情)回调,在其中接收自定义消息。
3. 希望停止接收消息,调用 removeAdvancedMsgListener 移除监听。该步骤不是必须的,客户可以按照业务需求调用。
代码示例如下:
V2TimAdvancedMsgListener listener = V2TimAdvancedMsgListener( onRecvC2CReadReceipt: (List<V2TimMessageReceipt> receiptList) {}, onRecvMessageModified: (V2TimMessage message) {}, onRecvMessageReadReceipts: (List<V2TimMessageReceipt> receiptList) {}, onRecvMessageRevoked: (String messageid) {}, onRecvNewMessage: (V2TimMessage message) { // 使用自定义消息 if(message.elemType == MessageElemType.V2TIM_ELEM_TYPE_CUSTOM){ String data = message.customElem.data; String desc = message.customElem.desc; String ext = message.customElem.extension; } }, onSendMessageProgress: (V2TimMessage message, int progress) {}, ); TencentImSDKPlugin.v2TIMManager .getMessageManager() .addAdvancedMsgListener(listener: listener);
五、接收富媒体消息
接收富媒体消息只能使用高级消息监听器,需要以下几步:
1. 接收方调用 addAdvancedMsgListener 接口设置高级消息监听。
2. 接收方通过监听回调 onRecvNewMessage(点击查看详情)获取消息 V2TimMessage。
3. 接收方解析 V2TIMMessage 消息中的 elemType 属性,并根据其类型进行二次解析,获取消息内部 Elem 中的具体内容。
4. 希望停止接收消息,调用 removeAdvancedMsgListener 移除监听。该步骤不是必须的,客户可以按照业务需求调用。
六、图片消息
一个图片消息会包含三种格式大小的图片,分别为原图、大图、微缩图(SDK 会在发送图片消息的时候自动生成微缩图、大图,客户不需要关心)。
大图:是将原图等比压缩。压缩后宽、高中较小的一个等于 720 像素。
缩略图:是将原图等比压缩。压缩后宽、高中较小的一个等于 198 像素。
在Flutter SDK 5.0.4版本后,多媒体消息在获取消息列表时不返回消息的url,需通过getMessageOnlineUrl(点击查看详情)获取。
在Flutter SDK 5.0.4版本后,多媒体消息默认不再返回 localurl,需通过 downloadMessage(点击查看详情)下载消息成功后才会返回。
示例代码向你演示如何从 V2TimMessage 中解析出图片消息内容:
V2TimAdvancedMsgListener listener = V2TimAdvancedMsgListener( onRecvC2CReadReceipt: (List<V2TimMessageReceipt> receiptList) {}, onRecvMessageModified: (V2TimMessage message) {}, onRecvMessageReadReceipts: (List<V2TimMessageReceipt> receiptList) {}, onRecvMessageRevoked: (String messageid) {}, onRecvNewMessage: (V2TimMessage message) async { // 使用图片消息 if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_IMAGE) { String path = message .imageElem.path; // 图片上传时的路径,消息发送者才会有这个字段,消息发送者可用这个字段将图片预先上屏,优化上屏体验。 for (var item in message.imageElem.imageList) { // 遍历大图、原图、缩略图 // 解析图片属性 int height = item.height; String localUrl = item.localUrl; int size = item.size; int type = item.type; // 大图 缩略图 原图 String url = item.url; String uuid = item.uuid; int width = item.width; } } // 获取多媒体消息URL V2TimValueCallback<V2TimMessageOnlineUrl> getMessageOnlineUrlRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .getMessageOnlineUrl( msgID: '', // 消息id ); if (getMessageOnlineUrlRes.code == 0) { // 获取成功 } // 下载多媒体消息 V2TimCallback downloadMessageRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .downloadMessage( msgID: '', // 消息id messageType: 3, // 消息类型 imageType: 0, // 图片类型,仅messageType为图片消息是有效 isSnapshot: false // 是否是视频封面,仅messageType为视频消息是有效 ); if (downloadMessageRes.code == 0) { // 下载成功 } }, onSendMessageProgress: (V2TimMessage message, int progress) {}, ); TencentImSDKPlugin.v2TIMManager .getMessageManager() .addAdvancedMsgListener(listener: listener);
七、视频消息
接收方收到视频消息后,一般需要在聊天界面显示一个视频预览图,当用户点击消息后,才会触发视频的播放。
Flutter SDK 会在空闲时间将视频消息下载到 App 本地,开发者可直接使用即可,本地视频和视频封面在 App 卸载时清除。示例代码向你演示如何从 V2TimMessage 中解析出视频消息内容:
在Flutter SDK 5.0.4版本后,多媒体消息在获取消息列表时不返回消息的url,需通过getMessageOnlineUrl (点击查看详情)获取。
在Flutter SDK 5.0.4版本后,多媒体消息不默认不再返回 localurl,需通过 downloadMessage(点击查看详情)下载消息成功后才会返回。
if(message.elemType == MessageElemType.V2TIM_ELEM_TYPE_VIDEO){ // 解析视频消息属性,封面、播放地址、宽高、大小等。 message.videoElem.UUID; message.videoElem.duration; message.videoElem.localSnapshotUrl; message.videoElem.localVideoUrl; message.videoElem.snapshotHeight; message.videoElem.snapshotPath; // … } // 获取多媒体消息URL V2TimValueCallback<V2TimMessageOnlineUrl> getMessageOnlineUrlRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .getMessageOnlineUrl( msgID: '', // 消息id ); if (getMessageOnlineUrlRes.code == 0) { // 获取成功 } // 下载多媒体消息 V2TimCallback downloadMessageRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .downloadMessage( msgID: '', // 消息id messageType: 5, // 消息类型 imageType: 0, // 图片类型,仅messageType为图片消息是有效 isSnapshot: false // 是否是视频封面,仅messageType为视频消息是有效 ); if (downloadMessageRes.code == 0) { // 下载成功 }
八、语音消息
Flutter SDK 会在空闲时间将语音消息下载到 App 本地,开发者可直接使用即可,本地语音消息在 App 卸载时清除。示例代码向你演示如何从 V2TimMessage 中解析出语音消息内容:
在Flutter SDK 5.0.4版本后,多媒体消息在获取消息列表时不返回消息的url,需通过getMessageOnlineUrl (点击查看详情)获取。
在Flutter SDK 5.0.4版本后,多媒体消息不默认不再返回 localurl,需通过 downloadMessage (点击查看详情)下载消息成功后才会返回。
if(message.elemType == MessageElemType.V2TIM_ELEM_TYPE_SOUND){ // 解析语音消息 播放地址,本地地址,大小,时长等。 message.soundElem.UUID; message.soundElem.dataSize; message.soundElem.duration; message.soundElem.localUrl; message.soundElem.url; // … // 获取多媒体消息URL V2TimValueCallback<V2TimMessageOnlineUrl> getMessageOnlineUrlRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .getMessageOnlineUrl( msgID: '', // 消息id ); if (getMessageOnlineUrlRes.code == 0) { // 获取成功 } // 下载多媒体消息 V2TimCallback downloadMessageRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .downloadMessage( msgID: '', // 消息id messageType: 4, // 消息类型 imageType: 0, // 图片类型,仅messageType为图片消息是有效 isSnapshot: false // 是否是视频封面,仅messageType为视频消息是有效 ); if (downloadMessageRes.code == 0) { // 下载成功 } }
九、文件消息
Flutter SDK 会在空闲时间将文件消息下载到 App 本地,开发者可直接使用即可,本地文件消息在 App 卸载时清除。示例代码向你演示如何从 V2TimMessage 中解析出文件消息内容:
在Flutter SDK 5.0.4版本后,多媒体消息在获取消息列表时不返回消息的url,需通过getMessageOnlineUrl (点击查看详情)获取。
在Flutter SDK 5.0.4版本后,多媒体消息不默认不再返回 localurl,需通过 downloadMessage (点击查看详情)下载消息成功后才会返回。
if(message.elemType == MessageElemType.V2TIM_ELEM_TYPE_FILE){ // 解析文件消息 文件名、文件大小、url等 message.fileElem.UUID; message.fileElem.fileName; message.fileElem.fileSize; message.fileElem.localUrl; message.fileElem.path; message.fileElem.url; // 获取多媒体消息URL V2TimValueCallback<V2TimMessageOnlineUrl> getMessageOnlineUrlRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .getMessageOnlineUrl( msgID: '', // 消息id ); if (getMessageOnlineUrlRes.code == 0) { // 获取成功 } // 下载多媒体消息 V2TimCallback downloadMessageRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .downloadMessage( msgID: '', // 消息id messageType: 6, // 消息类型 imageType: 0, // 图片类型,仅messageType为图片消息是有效 isSnapshot: false // 是否是视频封面,仅messageType为视频消息是有效 ); if (downloadMessageRes.code == 0) { // 下载成功 } }
十、地理位置消息
接收到地理位置消息后,接收方可直接从 locationElem 中解析出经纬度信息。
示例代码向你演示如何从 V2TimMessage 中解析出地理位置消息内容:
if(message.elemType == MessageElemType.V2TIM_ELEM_TYPE_LOCATION){ // 解析地理位置消息,经纬度、描述等 message.locationElem.desc; message.locationElem.latitude; message.locationElem.longitude;}
十一、表情消息
SDK 仅为表情消息提供消息透传的通道,消息内容字段参考 faceElem(点击查看详情)定义。其中 index 和 data 的内容由客户自定义。
例如发送方可设置 index = 1, data = "x12345",表示 “微笑” 表情。
接收方收到表情消息后解析出 1 和 "x12345",按照预设的规则将其展示为 “微笑” 表情。
示例代码向你演示如何从 V2TIMMessage 中解析出表情消息内容:
if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_FACE) { message.faceElem.data; message.faceElem.index;}
十二、群 tips 消息
群 tips 消息表示群组中,除了普通消息以外,用户会接收到的提示类消息。例如 “管理员将 alice 移除群聊” “bob 修改了群名称为 xxxx” 等。
注意:说明:
注意:群 tips 消息只有群聊成员会收到,单聊成员收不到。
群 tips 消息有多种类型,参考 V2TIMGroupTipsType (点击查看详情)的定义。
接收方接受到群 tips 消息后,一般需要做:
1. 解析出 V2TIMGroupTipsElem 中的各个字段
2. 根据 type 判断这个 tips 消息是什么类型
3. 根据类型,结合其他的字段,组装要显示的内容。
举个例子:
接收方解析出 type = V2TIM_GROUP_TIPS_TYPE_GROUP_INFO_CHANGE,表示这是个群资料变更通知。
接收方可以从 opMember 中获取到操作者信息,再从 groupChangeInfoList 获取到修改后的群名称。
此时,接收方可以将 “操作者” 和 “修改后的群名称” 组装起来,构造出一条群提示。例如 “alice 修改了群名称为 group123”。
示例代码向你演示如何从 V2TIMMessage 中解析出群 tips 消息内容:
if(message.elemType == MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS){ message.groupTipsElem.groupID; // 所属群组 message.groupTipsElem.type; // 群Tips类型 message.groupTipsElem.opMember; // 操作人资料 message.groupTipsElem.memberList; // 被操作人资料 message.groupTipsElem.groupChangeInfoList; // 群信息变更详情 message.groupTipsElem.memberChangeInfoList; // 群成员变更信息 message.groupTipsElem.memberCount; // 当前群在线人数}
十三、接收多个 Elem 的消息
1. 通过 Message 对象正常解析出第一个 Elem 对象。
2. 通过第一个 Elem 对象的 nextElem 方法获取下一个 Elem 对象,如果下一个 Elem 对象存在,会返回 Elem 对象实例,如果不存在,会返回 null。
示例代码如下:
if(message.textElem.nextElem!=null){ // 有下一个消息}