一、功能描述
·发送消息方法在核心类 TencentImSDKPlugin.v2TIMManager.getMessageManager()中。
·支持发送文本、自定义、富媒体消息,消息类型都是 V2TimMessage。
·V2TimMessage 中可以携带不同类型子类,表示不同类型的消息。
二、重点接口说明
注意:说明:
注意:下文中提到的发消息高级接口,指的都是 sendMessage。
接口说明如下:
Future<V2TimValueCallback<V2TimMessage>> sendMessage({ required String id, required String receiver, required String groupID, int priority = 0, bool onlineUserOnly = false, bool needReadReceipt = false, bool isExcludedFromUnreadCount = false, bool isExcludedFromLastMessage = false, Map<String, dynamic>? offlinePushInfo, String? cloudCustomData, String? localCustomData,})
参数说明:
| 参数 | 含义 | 单聊有效 | 群聊有效 | 说明 |
| id | 创建消息返回的 ID | YES | YES | 需要通过对应的 createXxxMessage 接口先行创建 |
| receiver | 单聊消息接收者 userID | YES | NO | 如果是发送 C2C 单聊消息,只需要指定 receiver 即可 |
| groupID | 群聊 groupID | NO | YES | 如果是发送群聊消息,只需要指定 groupID 即可 |
| priority | 消息优先级 | NO | YES | 请把重要消息设置为高优先级(例如红包、礼物消息),高频且不重要的消息设置为低优先级(例如点赞消息) |
| onlineUserOnly | 是否只有在线用户才能收到 | YES | YES | 如果设置为 YES ,接收方历史消息拉取不到,常被用于实现“对方正在输入”或群组里的非重要提示等弱提示功能 |
| offlinePushInfo | 离线推送信息 | YES | YES | 离线推送时携带的标题和内容 |
| needReadReceipt | 发送群消息是否支持已读 | NO | YES | 发送群消息是否支持已读 |
| isExcludedFromUnreadCount | 发送消息是否计入会话未读数 | YES | YES | 如果设置为 true,发送消息不会计入会话未读,默认为 false |
| isExcludedFromLastMessage | 发送消息是否计入会话 lastMessage | YES | YES | 如果设置为 true,发送消息不会计入会话 lastMessage,默认为 false |
| cloudCustomData | 消息云端数据 | YES | YES | 消息附带的额外的数据,存云端,消息的接收者可以访问到 |
| localCustomData | 消息本地数据 | YES | YES | 消息附带的额外的数据,存本地,消息的接收者不可以访问到,App 卸载后数据丢失 |
注意:说明:
注意:如果 groupID 和 receiver 同时设置,表示给 receiver 发送定向群消息。具体请参考 群定向消息。
三、发送文本消息
文本消息区分单聊和群聊,涉及的接口、传参有所区别。
发送文本消息可以采用两种接口:普通接口和高级接口。高级接口比普通接口能设置更多的发送参数(例如优先级、离线推送信息等)。
普通接口参考下文具体描述,高级接口就是上文中提到的 sendMessage。
五、高级接口
调用高级接口发送单聊文本消息分两步:
1. 调用 createTextMessage (点击查看详情) 创建文本消息。
2. 调用 sendMessage (点击查看详情) 发送消息。
示例代码如下:
// 创建文本消息 V2TimValueCallback<V2TimMsgCreateInfoResult> createTextMessageRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .createTextMessage( text: "test", // 文本信息 ); if (createTextMessageRes.code == 0) { // 文本信息创建成功 String? id = createTextMessageRes.data?.id; // 发送文本消息 // 在sendMessage时,若只填写receiver则发个人用户单聊消息 // 若只填写groupID则发群组消息 // 若填写了receiver与groupID则发群内的个人用户,消息在群聊中显示,只有指定receiver能看见 V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage( id: id!, // 创建的messageid receiver: "userID", // 接收人id groupID: "groupID", // 接收群组id priority: MessagePriorityEnum.V2TIM_PRIORITY_DEFAULT, // 消息优先级 onlineUserOnly: false, // 是否只有在线用户才能收到,如果设置为 true ,接收方历史消息拉取不到,常被用于实现“对方正在输入”或群组里的非重要提示等弱提示功能,该字段不支持 AVChatRoom。 isExcludedFromUnreadCount: false, // 发送消息是否计入会话未读数 isExcludedFromLastMessage: false, // 发送消息是否计入会话 lastMessage needReadReceipt: false, // 消息是否需要已读回执(只有 Group 消息有效,6.1 及以上版本支持,需要你购买旗舰版或企业版套餐) offlinePushInfo: OfflinePushInfo(), // 离线推送时携带的标题和内容 cloudCustomData: "", // 消息云端数据,消息附带的额外的数据,存云端,消息的接收者可以访问到 localCustomData: "" // 消息本地数据,消息附带的额外的数据,存本地,消息的接收者不可以访问到,App 卸载后数据丢失 ); if (sendMessageRes.code == 0) { // 发送成功 } }
七、高级接口
调用高级接口发送群聊文本消息分两步:
1. 调用 createTextMessage (点击查看详情) 创建文本消息。
2. 调用 sendMessage (点击查看详情) 发送消息。
示例代码如下:
// 创建文本消息 V2TimValueCallback<V2TimMsgCreateInfoResult> createTextMessageRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .createTextMessage( text: "test", // 文本信息 ); if (createTextMessageRes.code == 0) { // 文本信息创建成功 String? id = createTextMessageRes.data?.id; // 发送文本消息 // 在sendMessage时,若只填写receiver则发个人用户单聊消息 // 若只填写groupID则发群组消息 // 若填写了receiver与groupID则发群内的个人用户,消息在群聊中显示,只有指定receiver能看见 V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage( id: id!, // 创建的messageid receiver: "userID", // 接收人id groupID: "groupID", // 接收群组id priority: MessagePriorityEnum.V2TIM_PRIORITY_DEFAULT, // 消息优先级 onlineUserOnly: false, // 是否只有在线用户才能收到,如果设置为 true ,接收方历史消息拉取不到,常被用于实现“对方正在输入”或群组里的非重要提示等弱提示功能,该字段不支持 AVChatRoom。 isExcludedFromUnreadCount: false, // 发送消息是否计入会话未读数 isExcludedFromLastMessage: false, // 发送消息是否计入会话 lastMessage needReadReceipt: false, // 消息是否需要已读回执(只有 Group 消息有效,6.1 及以上版本支持,需要你购买旗舰版或企业版套餐) offlinePushInfo: OfflinePushInfo(), // 离线推送时携带的标题和内容 cloudCustomData: "", // 消息云端数据,消息附带的额外的数据,存云端,消息的接收者可以访问到 localCustomData: "" // 消息本地数据,消息附带的额外的数据,存本地,消息的接收者不可以访问到,App 卸载后数据丢失 ); if (sendMessageRes.code == 0) { // 发送成功 } }
八、发送自定义消息
自定义消息区分单聊和群聊,涉及的接口或者传参有所区别。发送自定义消息可以采用两种接口:普通接口和高级接口。
高级接口即上文中已介绍过的 sendMessage (点击查看详情),比普通接口能设置更多的发送参数(例如优先级、离线推送信息等)。
十、高级接口
调用高级接口发送单聊自定义消息分两步:
1. 调用 createCustomMessage (点击查看详情) 创建自定义消息。
2. 调用 sendMessage (点击查看详情) 发送消息。
示例代码如下:
// 创建自定义消息V2TimValueCallback<V2TimMsgCreateInfoResult> createCustomMessageRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createCustomMessage( data: '自定义data', desc: '自定义desc', extension: '自定义extension', ); if(createCustomMessageRes.code == 0){ String id = createCustomMessageRes.data.id; // 发送自定义消息 V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage(id: id, receiver: "userID", groupID: ""); if(sendMessageRes.code == 0){ // 发送成功 } }
十二、高级接口
调用高级接口发送群聊自定义消息分两步:
1. 调用 createCustomMessage (点击查看详情) 创建自定义消息。
2. 调用 sendMessage (点击查看详情) 发送消息。
代码示例如下:
// 创建自定义消息V2TimValueCallback<V2TimMsgCreateInfoResult> createCustomMessageRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createCustomMessage( data: '自定义data', desc: '自定义desc', extension: '自定义extension', ); if(createCustomMessageRes.code == 0){ String id = createCustomMessageRes.data.id; // 发送自定义消息 V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage(id: id, receiver: "", groupID: "groupID"); if(sendMessageRes.code == 0){ // 发送成功 } }
十三、发送富媒体消息
富媒体消息发送没有普通接口,都需要使用高级接口,步骤是:
1. 调用 createXxxMessage 创建指定类型的富媒体消息对象,其中 Xxx 表示具体的消息类型。
2. 调用 sendMessage(点击查看详情) 发送消息。
3. 在消息回调中获取消息是否发送成功或失败。
十四、图片消息
创建图片消息需要先获取到本地图片路径。
发送消息过程中,会先将图片文件上传至服务器,同时回调上传进度。上传成功后再发送消息。
如果你的项目需要支持Web,请查看Web兼容说明章节,发送图片的方式与移动端有不一致之处。
示例代码如下:
V2TimValueCallback<V2TimMsgCreateInfoResult> createImageMessageRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createImageMessage( imagePath: "本地图片绝对路径",); if (createImageMessageRes.code == 0) { String id = createImageMessageRes.data.id; V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin .v2TIMManager .getMessageManager() .sendMessage(id: id, receiver: "userID", groupID: "groupID"); if (sendMessageRes.code == 0) { // 发送成功 } }
十五、语音消息
创建语音消息需要先获取到本地语音文件路径和语音时长,其中语音时长可用于接收端 UI 显示。
发送消息过程中,会先将语音文件上传至服务器,同时回调上传进度。上传成功后再发送消息。
示例代码如下:
V2TimValueCallback<V2TimMsgCreateInfoResult> createSoundMessageRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createSoundMessage( soundPath: "本地录音文件绝对路径", duration: 10,// 录音时长 ); if (createSoundMessageRes.code == 0) { String id = createSoundMessageRes.data.id; V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin .v2TIMManager .getMessageManager() .sendMessage(id: id, receiver: "userID", groupID: "groupID"); if (sendMessageRes.code == 0) { // 发送成功 } }
十六、视频消息
创建视频消息需要先获取到本地视频文件路径、视频时长和视频快照,其中时长和快照可用于接收端 UI 显示。
发送消息过程中,会先将视频上传至服务器,同时回调上传进度。上传成功后再发送消息。
如果你的项目需要支持Web,请查看Web兼容说明章节,发送视频的方式与移动端有不一致之处。
示例代码如下:
V2TimValueCallback<V2TimMsgCreateInfoResult> createVideoMessageRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .createVideoMessage( videoFilePath: "本地视频文件绝对路径", type: "mp4", // 视频类型 duration: 10,// 视频时长 snapshotPath: "本地视频封面文件绝对路径", ); if (createVideoMessageRes.code == 0) { String id = createVideoMessageRes.data.id; V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin .v2TIMManager .getMessageManager() .sendMessage(id: id, receiver: "userID", groupID: "groupID"); if (sendMessageRes.code == 0) { // 发送成功 } }
十七、文件消息
创建文件消息需要先获取到本地文件路径。
发送消息过程中,会先将文件上传至服务器,同时回调上传进度。上传成功后再发送消息。
如果你的项目需要支持Web,请查看Web兼容说明章节,发送文件的方式与移动端有不一致之处。
示例代码如下:
V2TimValueCallback<V2TimMsgCreateInfoResult> createFileMessageRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .createFileMessage( filePath: "本地文件绝对路径", fileName: "文件名", ); if (createFileMessageRes.code == 0) { String id = createFileMessageRes.data.id; V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin .v2TIMManager .getMessageManager() .sendMessage(id: id, receiver: "userID", groupID: "groupID"); if (sendMessageRes.code == 0) { // 发送成功 } }
十八、位置消息
位置消息会直接发送经纬度,一般需要配合地图控件显示。
示例代码如下:
V2TimValueCallback<V2TimMsgCreateInfoResult> createLocationMessage = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .createLocationMessage( desc: "深圳市南山区深南大道",//位置信息摘要 longitude: 34,// 经度 latitude: 20, // 纬度 ); if (createLocationMessage.code == 0) { String id = createLocationMessage.data.id; V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin .v2TIMManager .getMessageManager() .sendMessage(id: id, receiver: "userID", groupID: "groupID"); if (sendMessageRes.code == 0) { // 发送成功 } }
十九、表情消息
表情消息会直接发送表情编码,通常接收端需要将其转换成对应的表情 icon。
示例代码如下:
V2TimValueCallback<V2TimMsgCreateInfoResult> createFaceMessageRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .createFaceMessage( index: 0, data: "", ); if (createFaceMessageRes.code == 0) { String id = createFaceMessageRes.data.id; V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin .v2TIMManager .getMessageManager() .sendMessage(id: id, receiver: "userID", groupID: "groupID"); if (sendMessageRes.code == 0) { // 发送成功 } }
20、Flutter for Web支持
IM SDK(tencent_cloud_chat_sdk) 4.1.1+2版本起,可极大兼容 Web 端。相比 Android 和 iOS 端,发送媒体及文件,步骤有不一致之处。如下:
由于 Web 特性,创建媒体及文件消息时,无法直接传入路径至 SDK。需要根据 Element ID 获取 input 的 DOM 节点,将选择文件后的 input DOM 传入。
·选取媒体建议使用 image_picker 包。
·选取文件建议使用 file_picker 包。
·示例代码中 getElementById 的值,若和F12控制台看到 input 的 id 不一致,请以实际为准。
21、发送图片
final ImagePicker _picker = ImagePicker();_sendImageFileOnWeb() async { final pickedFile = await _picker.pickImage(source: ImageSource.gallery); final imageContent = await pickedFile!.readAsBytes(); fileName = pickedFile.name; tempFile = File(pickedFile.path); fileContent = imageContent; html.Node? inputElem; inputElem = html.document .getElementById("__image_picker_web-file-input") ?.querySelector("input"); final convID = widget.conversationID; final convType = widget.conversationType == 1 ? ConvType.c2c : ConvType.group; final createImageMessageRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .createImageMessage(inputElement: inputElement); if (createImageMessageRes.code == 0) { String id = createImageMessageRes.data.id; V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin .v2TIMManager .getMessageManager() .sendMessage(id: id, receiver: "userID", groupID: "groupID"); if (sendMessageRes.code == 0) { // 发送成功 } }}
22、发送视频
final ImagePicker _picker = ImagePicker();_sendVideoFileOnWeb() async { final pickedFile = await _picker.pickVideo(source: ImageSource.gallery); final videoContent = await pickedFile!.readAsBytes(); fileName = pickedFile.name ?? ""; tempFile = File(pickedFile.path); fileContent = videoContent; if(fileName!.split(".")[fileName!.split(".").length – 1] != "mp4"){ Toast.showToast("视频消息仅限 mp4 格式", context); return; } html.Node? inputElem; inputElem = html.document .getElementById("__image_picker_web-file-input") ?.querySelector("input"); final convID = widget.conversationID; final convType = widget.conversationType == 1 ? ConvType.c2c : ConvType.group; final createVideoMessageRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .createVideoMessage(inputElement: inputElement, videoFilePath: "", type: "", duration: 0, snapshotPath: ""); if (createVideoMessageRes.code == 0) { String id = createVideoMessageRes.data.id; V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin .v2TIMManager .getMessageManager() .sendMessage(id: id, receiver: "userID", groupID: "groupID"); if (sendMessageRes.code == 0) { // 发送成功 } }}
23、发送文件
_sendFileOnWeb(){ final convID = widget.conversationID; final convType = widget.conversationType == 1 ? ConvType.c2c : ConvType.group; FilePickerResult? result = await FilePicker.platform.pickFiles(); if (result != null && result.files.isNotEmpty) { html.Node? inputElem; inputElem = html.document .getElementById("__file_picker_web-file-input") ?.querySelector("input"); fileName = result.files.single.name; final createFileMessageRes = await TencentImSDKPlugin.v2TIMManager .getMessageManager() .createFileMessage(inputElement: inputElement, filePath: "", fileName: fileName); if (createFileMessageRes.code == 0) { String id = createFileMessageRes.data.id; V2TimValueCallback<V2TimMessage> sendMessageRes = await TencentImSDKPlugin .v2TIMManager .getMessageManager() .sendMessage(id: id, receiver: "userID", groupID: "groupID"); if (sendMessageRes.code == 0) { // 发送成功 } } }}