差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
后一修订版 两侧同时换到之后的修订记录
im:android:basics:message [2019/11/25 08:18]
huanxinfudh [根据关键字搜索会话消息]
im:android:basics:message [2020/08/10 04:42]
zhaoliang [群消息已读回调]
行 19: 行 19:
 </​code>​ </​code>​
  
-====发送语音消息==== +====发送表情消息==== 
 +发表情消息实质上是发文本消息。接收方收到文本消息后,首先查询文本消息是否是表情消息,如果是,则显示该文本消息为对应的表情图片。可以参考[[https://​unicode.org/​emoji/​charts/​full-emoji-list.html |emoji列表]]来做表情图片和对应的文本字符串的映射。也可以自行维护表情图片和文本字符串的映射。
 <code java> <code java>
-//filePath为语音件路径length录音时间(秒) +//创建一条表情消息。表情消息实质上是一个字消息。emojiCode是表情图片对应的文本字符串toChatUsername对方用户或者群聊的id,后文皆是如此 
-EMMessage message = EMMessage.createVoiceSendMessage(filePath, length, toChatUsername);​+EMMessage message = EMMessage.createTxtSendMessage(emojiCode, toChatUsername);​
 //​如果是群聊,设置chattype,默认是单聊 //​如果是群聊,设置chattype,默认是单聊
 if (chatType == CHATTYPE_GROUP) if (chatType == CHATTYPE_GROUP)
  message.setChatType(ChatType.GroupChat);​  message.setChatType(ChatType.GroupChat);​
 +//​发送消息
 EMClient.getInstance().chatManager().sendMessage(message);​ EMClient.getInstance().chatManager().sendMessage(message);​
 </​code>​ </​code>​
  
 +====发送语音消息====
 +
 +<code java>
 +//​voiceUri为语音文件本地资源标志符,length为录音时间(秒) ​
 +EMMessage message = EMMessage.createVoiceSendMessage(voiceUri,​ length, toChatUsername); ​
 +//​如果是群聊,设置chattype,默认是单聊 ​
 +if (chatType == CHATTYPE_GROUP) ​
 +    message.setChatType(ChatType.GroupChat); ​
 +EMClient.getInstance().chatManager().sendMessage(message);​
 +</​code>​
 +发送成功后,获取语音消息附件:
 +<​code>​
 +EMVoiceMessageBody voiceBody = (EMVoiceMessageBody) msg.getBody();​
 +//​获取语音文件在服务器的地址
 +String voiceRemoteUrl = voiceBody.getRemoteUrl();​
 +//​本地语音文件的资源路径
 +Uri voiceLocalUri = voiceBody.getLocalUri();​
 +</​code>​
 +''​适配AndroidQ及以上手机时,获取本地资源请调用voiceBody.getLocalUri(),相应的voiceBody.getLocalUrl()方法已经被废弃!''​
 ====发送视频消息==== ====发送视频消息====
  
 <code java> <code java>
-//videoPath为视频本地路径thumbPath为视频预览图路径,videoLength为视频时间长度 +//videoLocalUri为视频本地资源标志符thumbLocalUri为视频预览图路径,videoLength为视频时间长度 
-EMMessage message = EMMessage.createVideoSendMessage(videoPaththumbPath, videoLength,​ toChatUsername);​+EMMessage message = EMMessage.createVideoSendMessage(videoLocalUrithumbLocalUri, videoLength,​ toChatUsername);​
 //​如果是群聊,设置chattype,默认是单聊 //​如果是群聊,设置chattype,默认是单聊
 if (chatType == CHATTYPE_GROUP) if (chatType == CHATTYPE_GROUP)
- message.setChatType(ChatType.GroupChat);​+   message.setChatType(ChatType.GroupChat);​
 EMClient.getInstance().chatManager().sendMessage(message);​ EMClient.getInstance().chatManager().sendMessage(message);​
 </​code>​ </​code>​
 +发送成功后,获取视频消息缩略图及附件 
 +<​code>​ 
 +EMVideoMessageBody videoBody = (EMVideoMessageBody) message.getBody();​ 
 +//​获取视频文件在服务器的路径 
 +String videoRemoteUrl = videoBody.getRemoteUrl();​ 
 +//​获取缩略图在服务器的路径 
 +String thumbnailUrl = videoBody.getThumbnailUrl();​ 
 +//​本地视频文件的资源路径 
 +Uri videoLocalUri = videoBody.getLocalUri();​ 
 +//​本地视频缩略图资源路径 
 +Uri localThumbUri = videoBody.getLocalThumbUri();​ 
 +</​code>​ 
 +''​适配AndroidQ及以上手机时,获取本地资源请调用videoBody.getLocalUri(),相应的videoBody.getLocalUrl()方法已经被废弃!''​
 ====发送图片消息==== ====发送图片消息====
  
 <code java> <code java>
-//imagePath为图片本地路径,false为不发送原图(默认超过100k的图片会压缩后发给对方),需要发送原图传true +//imageUri为图片本地资源标志符,false为不发送原图(默认超过100k的图片会压缩后发给对方),需要发送原图传true  
-EMMessage.createImageSendMessage(imagePath, false, toChatUsername);​ +EMMessage.createImageSendMessage(imageUri, false, toChatUsername);​  
-//​如果是群聊,设置chattype,默认是单聊 +//​如果是群聊,设置chattype,默认是单聊  
-if (chatType == CHATTYPE_GROUP) +if (chatType == CHATTYPE_GROUP)  
- message.setChatType(ChatType.GroupChat);​+    message.setChatType(ChatType.GroupChat); ​
 EMClient.getInstance().chatManager().sendMessage(message);​ EMClient.getInstance().chatManager().sendMessage(message);​
 </​code>​ </​code>​
 +发送成功后,获取图片消息缩略图及附件 
 +<​code>​ 
 +EMImageMessageBody imgBody = (EMImageMessageBody) message.getBody();​ 
 +//​获取图片文件在服务器的路径 
 +String imgRemoteUrl = imgBody.getRemoteUrl();​ 
 +//​获取图片缩略图在服务器的路径 
 +String thumbnailUrl = imgBody.getThumbnailUrl();​ 
 +//​本地图片文件的资源路径 
 +Uri imgLocalUri = imgBody.getLocalUri();​ 
 +//​本地图片缩略图资源路径 
 +Uri thumbnailLocalUri = imgBody.thumbnailLocalUri();​ 
 +</​code>​ 
 +''​适配AndroidQ及以上手机时,获取本地资源请调用imgBody.getLocalUri(),相应的imgBody.getLocalUrl()方法已经被废弃!''​
 ====发送地理位置消息==== ====发送地理位置消息====
  
行 66: 行 110:
  
 <code java> <code java>
-EMMessage message = EMMessage.createFileSendMessage(filePath, toChatUsername);​+//​fileLocalUri为本地资源标志符 
 +EMMessage message = EMMessage.createFileSendMessage(fileLocalUri, toChatUsername);​
 // 如果是群聊,设置chattype,默认是单聊 // 如果是群聊,设置chattype,默认是单聊
 if (chatType == CHATTYPE_GROUP) if (chatType == CHATTYPE_GROUP)
- message.setChatType(ChatType.GroupChat);​+    ​message.setChatType(ChatType.GroupChat);​
 EMClient.getInstance().chatManager().sendMessage(message);​ EMClient.getInstance().chatManager().sendMessage(message);​
 </​code>​ </​code>​
 +发送成功后,获取文件消息附件 
 +<​code>​ 
 +EMNormalFileMessageBody fileMessageBody = (EMNormalFileMessageBody) message.getBody();​ 
 +//​获取文件在服务器的路径 
 +String fileRemoteUrl = fileMessageBody.getRemoteUrl();​ 
 +//​本地文件的资源路径 
 +Uri fileLocalUri = fileMessageBody.getLocalUri();​ 
 +</​code>​ 
 +''​适配AndroidQ及以上手机时,获取本地资源请调用fileMessageBody.getLocalUri(),相应的fileMessageBody.getLocalUrl()方法已经被废弃!''​
 ==== 发送透传消息 ==== ==== 发送透传消息 ====
  
行 89: 行 142:
 EMClient.getInstance().chatManager().sendMessage(cmdMsg);​ EMClient.getInstance().chatManager().sendMessage(cmdMsg);​
 </​code>​ </​code>​
 +
 +==== 发送自定义类型消息 ====
 +用户可以在以上几种消息之外,自己定义消息类型,方便用户的业务处理。
 +自定义消息类型支持用户自己设置一个消息的类型名称,这样用户可以添加多种自定义消息。
 +自定义消息的内容部分是key,value格式的,用户需要自己添加并解析该内容。
 +
 +<code java>
 +
 +EMMessage customMessage = EMMessage.createSendMessage(EMMessage.Type.CUSTOM);​
 +// event为需要传递的自定义消息事件,比如礼物消息,可以设置event = "​gift"​
 +EMCustomMessageBody customBody = new EMCustomMessageBody(event);​
 +// params类型为Map<​String,​ String>
 +customBody.setParams(params);​
 +customMessage.addBody(customBody);​
 +// to指另一方环信id(或者群组id,聊天室id)
 +customMessage.setTo(to);​
 +// 如果是群聊,设置chattype,默认是单聊
 +customMessage.setChatType(chatType);​
 +EMClient.getInstance().chatManager().sendMessage(customMessage);​
 +        ​
 +</​code>​
 +
 +
 +==== 设置群消息是否需要已读回执(增值服务) ====
 +当消息为群消息时,消息发送方(目前为管理员和群主)可以设置此消息是否需要已读回执,如需要,则设置EMMessage的方法setIsNeedGroupAck()为YES,之后发送。
 +<​code>​
 +public EMMessage createDingMessage(String to, String content) {
 +        EMMessage message = EMMessage.createTxtSendMessage(content,​ to);
 +        message.setIsNeedGroupAck(true);​
 +        return message;
 +    }
 +    ​
 + </​code>​
 +
 +
 +==== 发送群消息已读回执 ====
 +<code objc>
 +public void sendAckMessage(EMMessage message) {
 +        if (!validateMessage(message)) {
 +            return;
 +        }
 +
 +        if (message.isAcked()) {
 +            return;
 +        }
 +
 +        // May a user login from multiple devices, so do not need to send the ack msg.
 +        if (EMClient.getInstance().getCurrentUser().equalsIgnoreCase(message.getFrom())) {
 +            return;
 +        }
 +
 +        try {
 +            if (message.isNeedGroupAck() && !message.isUnread()) {
 +                String to = message.conversationId();​ // do not user getFrom() here
 +                String msgId = message.getMsgId();​
 +                EMClient.getInstance().chatManager().ackGroupMessageRead(to,​ msgId, ((EMTextMessageBody)message.getBody()).getMessage());​
 +                message.setUnread(false);​
 +                EMLog.i(TAG,​ "Send the group ack cmd-type message."​);​
 +            }
 +        } catch (Exception e) {
 +            EMLog.d(TAG,​ e.getMessage());​
 +        }
 +    }
 +</​code>​
 +
 +当发送群已读回执后,消息发送方对应EMMessage的groupAckCount属性会有相应变化;
 +
 +
 +==== 群消息已读回调 ====
 +群消息已读回调在消息监听类EMMessageListener中。
 +<​code>​
 + /**
 + * \~chinese
 + * 接受到群组消息体的已读回执,​ 消息的接收方已经阅读此消息。
 + */
 +         void onGroupMessageRead(List<​EMGroupReadAck>​ groupReadAcks) {
 +        }
 +
 +</​code>​
 +
 +==== 获取群消息已读回执详情 ====
 +如果想实现群消息已读回执的列表显示,可以通过下列接口获取到已读回执的详情。
 +
 +<​code>​
 +/**
 + * \~chinese
 + * 从服务器获取群组消息回执详情
 + * @param msgId 消息id
 + * @param pageSize 获取的页面大小
 + * @param startAckId 已读回执的id,如果为空,从最新的回执向前开始获取
 + * @return 返回消息列表和用于继续获取群消息回执的Cursor
 + */
 + public void asyncFetchGroupReadAcks(final String msgId, final int pageSize,
 + final String startAckId, final EMValueCallBack<​EMCursorResult<​EMGroupReadAck>>​ callBack) {
 + EMClient.getInstance().execute(new Runnable() {
 + @Override
 + public void run() {
 + try {
 + callBack.onSuccess(fetchGroupReadAcks(msgId,​ pageSize, startAckId));​
 + } catch (HyphenateException e) {
 + callBack.onError(e.getErrorCode(),​ e.getDescription());​
 + }
 + }
 + });
 + }
 +</​code>​
 +
  
 ==== 发送扩展消息 ==== ==== 发送扩展消息 ====
行 153: 行 313:
 EMClient.getInstance().chatManager().removeMessageListener(msgListener);​ EMClient.getInstance().chatManager().removeMessageListener(msgListener);​
 </​code>​ </​code>​
 +===== 下载缩略图及附件 =====
 +
 +==== 下载缩略图 ====
 +
 +如果设置了自动下载,即EMClient.getInstance().getOptions().getAutodownloadThumbnail()为true,SDK接收到消息后会下载缩略图;\\
 +如果没有设置自动下载,需主动调用EMClient.getInstance().chatManager().downloadThumbnail(message)下载。\\
 +下载完成后,调用相应消息body的thumbnailLocalUri()去获取缩略图路径。\\
 +例如:
 +<​code>​
 +EMImageMessageBody imgBody = (EMImageMessageBody) message.getBody();​
 +//​本地图片缩略图资源路径
 +Uri thumbnailLocalUri = imgBody.thumbnailLocalUri();​
 +</​code>​
 +==== 下载附件 ====
 +
 +下载附件的方法为:EMClient.getInstance().chatManager().downloadAttachment(message);​\\
 +下载完成后,调用相应消息body的getLocalUri()去获取附件路径。\\
 +例如:
 +<​code>​
 +EMImageMessageBody imgBody = (EMImageMessageBody) message.getBody();​
 +//​本地图片文件的资源路径
 +Uri imgLocalUri = imgBody.getLocalUri();​
 +</​code>​
 +
 ===== 监听消息状态 ===== ===== 监听消息状态 =====
  
行 240: 行 424:
  
 ===== 撤回消息功能 ===== ===== 撤回消息功能 =====
-消息撤回功能可以撤回一定时间内发送出去的消息,目前只能是两分钟,不能修改。+消息撤回功能可以撤回一定时间内发送出去的消息,消息撤回时限默认2分钟,可根据开发者需求以AppKey为单位进行单独设置,如需修改请联系环信商务
  
 消息撤回为增值功能,请联系环信商务开通。 消息撤回为增值功能,请联系环信商务开通。
行 286: 行 470:
  
 ===== 根据关键字搜索会话消息 ===== ===== 根据关键字搜索会话消息 =====
-<​code>​+<​code ​java>
 List<​EMMessage>​ messages = conversation.searchMsgFromDB(keywords,​ timeStamp, maxCount, from, EMConversation.EMSearchDirection.UP);​ List<​EMMessage>​ messages = conversation.searchMsgFromDB(keywords,​ timeStamp, maxCount, from, EMConversation.EMSearchDirection.UP);​
 </​code>​ </​code>​
  
 ===== 导入消息到数据库 ===== ===== 导入消息到数据库 =====
 +如果有从2.x SDK或者其他第三方SDK升级到目前3.x SDK的需要,可以使用下面的接口,构造EMMessage 对象,将历史消息导入到本地数据库中。
 <code java> <code java>
 EMClient.getInstance().chatManager().importMessages(msgs);​ EMClient.getInstance().chatManager().importMessages(msgs);​
 </​code>​ </​code>​
 +
 +===== 插入消息 =====
 +
 +<code java>
 +//​根据会话插入消息
 +EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username);​
 +conversation.insertMessage(message);​
 +
 +//​直接插入消息
 +EMClient.getInstance().chatManager().saveMessage(message);​
 +</​code>​
 +
  
 ===== Demo 及 SDK 下载 ===== ===== Demo 及 SDK 下载 =====