差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
im:android:basics:message [2020/08/10 03:58] zhaoliang [发送自定义类型消息] |
im:android:basics:message [2022/05/18 09:02] jennifer.zeng [接收消息] |
||
---|---|---|---|
行 1: | 行 1: | ||
====== 消息 ====== | ====== 消息 ====== | ||
+ | 更新时间:2021-12-31 | ||
+ | |||
+ | 新版文档见:[[ccim:android:message1|消息管理 Android]]。 | ||
---- | ---- | ||
行 31: | 行 34: | ||
</code> | </code> | ||
- | ====发送语音消息==== | + | ==== 发送语音消息 ==== |
<code java> | <code java> | ||
- | //voiceUri为语音文件本地资源标志符,length为录音时间(秒) | + | //voiceUri 为语音文件本地资源标志符,length 为录音时间(秒) |
EMMessage message = EMMessage.createVoiceSendMessage(voiceUri, length, toChatUsername); | EMMessage message = EMMessage.createVoiceSendMessage(voiceUri, length, 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> | <code> | ||
EMVoiceMessageBody voiceBody = (EMVoiceMessageBody) msg.getBody(); | EMVoiceMessageBody voiceBody = (EMVoiceMessageBody) msg.getBody(); | ||
行 49: | 行 54: | ||
Uri voiceLocalUri = voiceBody.getLocalUri(); | Uri voiceLocalUri = voiceBody.getLocalUri(); | ||
</code> | </code> | ||
- | ''适配AndroidQ及以上手机时,获取本地资源请调用voiceBody.getLocalUri(),相应的voiceBody.getLocalUrl()方法已经被废弃!'' | + | ''适配 AndroidQ 及以上手机时,获取本地资源请调用 voiceBody.getLocalUri(),相应的 voiceBody.getLocalUrl() 方法已经被废弃!'' |
- | ====发送视频消息==== | + | ==== 发送视频消息 ==== |
<code java> | <code java> | ||
- | //videoLocalUri为视频本地资源标志符,thumbLocalUri为视频预览图路径,videoLength为视频时间长度 | + | //videoLocalUri 为视频本地资源标志符,thumbLocalUri 为视频预览图路径,videoLength 为视频时间长度 |
EMMessage message = EMMessage.createVideoSendMessage(videoLocalUri, thumbLocalUri, videoLength, toChatUsername); | EMMessage message = EMMessage.createVideoSendMessage(videoLocalUri, thumbLocalUri, 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> | <code> | ||
EMVideoMessageBody videoBody = (EMVideoMessageBody) message.getBody(); | EMVideoMessageBody videoBody = (EMVideoMessageBody) message.getBody(); | ||
行 72: | 行 79: | ||
Uri localThumbUri = videoBody.getLocalThumbUri(); | Uri localThumbUri = videoBody.getLocalThumbUri(); | ||
</code> | </code> | ||
- | ''适配AndroidQ及以上手机时,获取本地资源请调用videoBody.getLocalUri(),相应的videoBody.getLocalUrl()方法已经被废弃!'' | + | ''适配 AndroidQ 及以上手机时,获取本地资源请调用 videoBody.getLocalUri(),相应的 videoBody.getLocalUrl() 方法已经被废弃!'' |
- | ====发送图片消息==== | + | ==== 发送图片消息 ==== |
<code java> | <code java> | ||
- | //imageUri为图片本地资源标志符,false为不发送原图(默认超过100k的图片会压缩后发给对方),需要发送原图传true | + | //imageUri 为图片本地资源标志符,false 为不发送原图(默认超过 100k 的图片会压缩后发给对方),需要发送原图传 true |
EMMessage.createImageSendMessage(imageUri, 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> | <code> | ||
EMImageMessageBody imgBody = (EMImageMessageBody) message.getBody(); | EMImageMessageBody imgBody = (EMImageMessageBody) message.getBody(); | ||
行 95: | 行 104: | ||
Uri thumbnailLocalUri = imgBody.thumbnailLocalUri(); | Uri thumbnailLocalUri = imgBody.thumbnailLocalUri(); | ||
</code> | </code> | ||
- | ''适配AndroidQ及以上手机时,获取本地资源请调用imgBody.getLocalUri(),相应的imgBody.getLocalUrl()方法已经被废弃!'' | + | ''适配 AndroidQ 及以上手机时,获取本地资源请调用 imgBody.getLocalUri(),相应的 imgBody.getLocalUrl() 方法已经被废弃!'' |
====发送地理位置消息==== | ====发送地理位置消息==== | ||
行 107: | 行 116: | ||
</code> | </code> | ||
- | ====发送文件消息==== | + | ==== 发送文件消息 ==== |
<code java> | <code java> | ||
- | //fileLocalUri为本地资源标志符 | + | //fileLocalUri 为本地资源标志符 |
EMMessage message = EMMessage.createFileSendMessage(fileLocalUri, toChatUsername); | 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> | <code> | ||
EMNormalFileMessageBody fileMessageBody = (EMNormalFileMessageBody) message.getBody(); | EMNormalFileMessageBody fileMessageBody = (EMNormalFileMessageBody) message.getBody(); | ||
行 125: | 行 136: | ||
Uri fileLocalUri = fileMessageBody.getLocalUri(); | Uri fileLocalUri = fileMessageBody.getLocalUri(); | ||
</code> | </code> | ||
- | ''适配AndroidQ及以上手机时,获取本地资源请调用fileMessageBody.getLocalUri(),相应的fileMessageBody.getLocalUrl()方法已经被废弃!'' | + | ''适配 AndroidQ 及以上手机时,获取本地资源请调用 fileMessageBody.getLocalUri(),相应的 fileMessageBody.getLocalUrl() 方法已经被废弃!'' |
==== 发送透传消息 ==== | ==== 发送透传消息 ==== | ||
- | 透传消息能做什么:头像、昵称的更新等。可以把透传消息理解为一条指令,通过发送这条指令给对方,告诉对方要做的 action,收到消息可以自定义处理的一种消息。(透传消息不会存入本地数据库中,所以在 UI 上是不会显示的)。另,以“em_”和“easemob::”开头的action为内部保留字段,注意不要使用 | + | 透传消息能做什么:头像、昵称的更新等。可以把透传消息理解为一条指令,通过发送这条指令给对方,告诉对方要做的 action,收到消息可以自定义处理的一种消息。(透传消息不会存入本地数据库中,所以在 UI 上是不会显示的)。另,以 “em_” 和 “easemob::” 开头的 action 为内部保留字段,注意不要使用 |
<code java> | <code java> | ||
行 166: | 行 177: | ||
==== 设置群消息是否需要已读回执(增值服务) ==== | ==== 设置群消息是否需要已读回执(增值服务) ==== | ||
- | 当消息为群消息时,消息发送方(目前为管理员和群主)可以设置此消息是否需要已读回执,如需要,则设置EMMessage的方法setIsNeedGroupAck()为YES,之后发送。 | + | |
+ | 当消息为群消息时,消息发送方(目前为管理员和群主)可以设置此消息是否需要已读回执,如需要,则设置 EMMessage 的方法 setIsNeedGroupAck() 为 YES,之后发送。 | ||
<code> | <code> | ||
public EMMessage createDingMessage(String to, String content) { | public EMMessage createDingMessage(String to, String content) { | ||
行 175: | 行 188: | ||
| | ||
</code> | </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 use 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) { | ||
+ | |||
+ | } | ||
+ | </code> | ||
行 204: | 行 282: | ||
<code java> | <code java> | ||
- | EMClient.getInstance().chatManager().addMessageListener(msgListener); | ||
EMMessageListener msgListener = new EMMessageListener() { | EMMessageListener msgListener = new EMMessageListener() { | ||
行 236: | 行 313: | ||
} | } | ||
}; | }; | ||
+ | EMClient.getInstance().chatManager().addMessageListener(msgListener); | ||
记得在不需要的时候移除listener,如在activity的onDestroy()时 | 记得在不需要的时候移除listener,如在activity的onDestroy()时 | ||
行 281: | 行 359: | ||
//获取此会话的所有消息 | //获取此会话的所有消息 | ||
List<EMMessage> messages = conversation.getAllMessages(); | List<EMMessage> messages = conversation.getAllMessages(); | ||
- | //SDK初始化加载的聊天记录为20条,到顶时需要去DB里获取更多 | + | //SDK初始化每个会话加载的聊天记录为1条,可以去DB里获取更多 |
//获取startMsgId之前的pagesize条消息,此方法获取的messages SDK会自动存入到此会话中,APP中无需再次把获取到的messages添加到会话中 | //获取startMsgId之前的pagesize条消息,此方法获取的messages SDK会自动存入到此会话中,APP中无需再次把获取到的messages添加到会话中 | ||
List<EMMessage> messages = conversation.loadMoreMsgFromDB(startMsgId, pagesize); | List<EMMessage> messages = conversation.loadMoreMsgFromDB(startMsgId, pagesize); | ||
行 332: | 行 410: | ||
* @param conversationId 会话名称 | * @param conversationId 会话名称 | ||
* @param type 会话类型 | * @param type 会话类型 | ||
- | * @param pageSize 获取的页面大小 | + | * @param pageSize 获取的页面大小(一次最多50条) |
* @param startMsgId 漫游消息的开始消息id,如果为空,从最新的消息向前开始获取 | * @param startMsgId 漫游消息的开始消息id,如果为空,从最新的消息向前开始获取 | ||
* @return 返回消息列表和用于继续获取历史消息的Cursor | * @return 返回消息列表和用于继续获取历史消息的Cursor | ||
行 348: | 行 426: | ||
*/ | */ | ||
public void asyncFetchHistoryMessage(String conversationId, EMConversationType type, int pageSize, String startMsgId, EMValueCallBack<EMCursorResult<EMMessage>> callBack) | public void asyncFetchHistoryMessage(String conversationId, EMConversationType type, int pageSize, String startMsgId, EMValueCallBack<EMCursorResult<EMMessage>> callBack) | ||
+ | </code> | ||
+ | |||
+ | ===== 从服务器获取会话列表 ===== | ||
+ | |||
+ | ''该功能需联系商务进行开通,开通后默认用户可以拉取 7 天内的 10 个会话和每个会话中最新一条聊天记录,如需调整会话数量请联系环信商务经理(您可以在环信通讯云管理后台首页,扫描二维码联系您的商务经理)。'' | ||
+ | |||
+ | 建议此 API 在首次安装应用时或者本地没有会话的时候调用,其他时候使用本地的会话 API 即可。 | ||
+ | |||
+ | |||
+ | <code> | ||
+ | EMClient.getInstance().chatManager().asyncFetchConversationsFromServer(new EMValueCallBack<Map<String, EMConversation>>() { | ||
+ | @Override | ||
+ | public void onSuccess(Map<String, EMConversation> value) { | ||
+ | // 获取会话成功后的处理逻辑 | ||
+ | } | ||
+ | @Override | ||
+ | public void onError(int error, String errorMsg) { | ||
+ | // 获取会话失败处理逻辑 | ||
+ | } | ||
+ | }); | ||
</code> | </code> | ||
行 359: | 行 457: | ||
</code> | </code> | ||
+ | ===== 消息已读回执 ===== | ||
+ | 消息已读回执功能目前仅适用于单聊(ChatType.Chat),推荐使用方案为会话已读回执(conversation ack)+单条消息已读回执(read ack)结合实现,可减少发送read ack消息量。\\ | ||
+ | **''注:群消息已读回执功能为增值服务,具体使用请跳转到[[http://docs-im.easemob.com/im/android/basics/message#%E8%AE%BE%E7%BD%AE%E7%BE%A4%E6%B6%88%E6%81%AF%E6%98%AF%E5%90%A6%E9%9C%80%E8%A6%81%E5%B7%B2%E8%AF%BB%E5%9B%9E%E6%89%A7_%E5%A2%9E%E5%80%BC%E6%9C%8D%E5%8A%A1|群消息已读回执]]。''** | ||
+ | ==== 发送已读回执消息 ==== | ||
+ | 推荐进入会话首先发送会话已读回执(conversation ack)。 | ||
+ | <code java> | ||
+ | try { | ||
+ | EMClient.getInstance().chatManager().ackConversationRead(conversationId); | ||
+ | } catch (HyphenateException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | </code> | ||
+ | 在会话页面,可以在接收到消息时,根据消息类型发送消息已读回执(read ack),如下所示 | ||
+ | <code java> | ||
+ | EMClient.getInstance().chatManager().addMessageListener(new EMMessageListener() { | ||
+ | ...... | ||
+ | | ||
+ | @Override | ||
+ | public void onMessageReceived(List<EMMessage> messages) { | ||
+ | ...... | ||
+ | sendReadAck(message); | ||
+ | ...... | ||
+ | } | ||
+ | | ||
+ | ...... | ||
+ | }); | ||
+ | |||
+ | /** | ||
+ | * 发送已读回执 | ||
+ | * @param message | ||
+ | */ | ||
+ | public void sendReadAck(EMMessage message) { | ||
+ | //是接收的消息,未发送过read ack消息且是单聊 | ||
+ | if(message.direct() == EMMessage.Direct.RECEIVE | ||
+ | && !message.isAcked() | ||
+ | && message.getChatType() == EMMessage.ChatType.Chat) { | ||
+ | EMMessage.Type type = message.getType(); | ||
+ | //视频,语音及文件需要点击后再发送,这个可以根据需求进行调整 | ||
+ | if(type == EMMessage.Type.VIDEO || type == EMMessage.Type.VOICE || type == EMMessage.Type.FILE) { | ||
+ | return; | ||
+ | } | ||
+ | try { | ||
+ | EMClient.getInstance().chatManager().ackMessageRead(message.getFrom(), message.getMsgId()); | ||
+ | } catch (HyphenateException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== 监听已读回执回调 ==== | ||
+ | (1)设置会话已读回执的监听 | ||
+ | <code java> | ||
+ | EMClient.getInstance().chatManager().addConversationListener(new EMConversationListener() { | ||
+ | ...... | ||
+ | |||
+ | @Override | ||
+ | public void onConversationRead(String from, String to) { | ||
+ | //添加刷新页面通知等逻辑 | ||
+ | } | ||
+ | }); | ||
+ | </code> | ||
+ | 接收到会话已读回执(channel ack)回调后,SDK会在内部将会话相关消息置为对方已读,开发者需要在接收到此回调后,进行页面刷新等操作。\\ | ||
+ | |||
+ | (2)设置消息已读回执的监听 | ||
+ | <code java> | ||
+ | EMClient.getInstance().chatManager().addMessageListener(new EMMessageListener() { | ||
+ | ...... | ||
+ | |||
+ | @Override | ||
+ | public void onMessageRead(List<EMMessage> messages) { | ||
+ | //添加刷新消息等逻辑 | ||
+ | } | ||
+ | |||
+ | ...... | ||
+ | }); | ||
+ | </code> | ||
+ | 接收到read ack回调后,SDK会在内部将消息置为对方已读,开发者需要在接收到此回调后,进行消息刷新等操作。 | ||
+ | |||
+ | **注:判断是否对方已读根据消息的''isAcked()''方法进行判断,返回true为对方已读,开发者可以根据此字段进行UI界面的展示及刷新。** | ||
+ | |||
+ | ===== 会话已读回执 ===== | ||
+ | |||
+ | 会话已读回执用于需要获知接收方是否阅读消息的场景,目前仅适用于单聊(ChatType.Chat)。\\ | ||
+ | **''注:群消息已读回执功能为增值服务,具体使用请跳转到[[http://docs-im.easemob.com/im/android/basics/message#%E8%AE%BE%E7%BD%AE%E7%BE%A4%E6%B6%88%E6%81%AF%E6%98%AF%E5%90%A6%E9%9C%80%E8%A6%81%E5%B7%B2%E8%AF%BB%E5%9B%9E%E6%89%A7_%E5%A2%9E%E5%80%BC%E6%9C%8D%E5%8A%A1|群消息已读回执]]。''** | ||
+ | |||
+ | ==== 发送已读回执消息 ==== | ||
+ | |||
+ | 推荐进入会话页面,根据会话是否有未读消息,发送会话已读回执(conversation ack),有则发送,没有则不再发送。\\ | ||
+ | <code java> | ||
+ | try { | ||
+ | EMClient.getInstance().chatManager().ackConversationRead(conversationId); | ||
+ | } catch (HyphenateException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | </code> | ||
+ | 注:该方法为异步方法,需要捕捉异常。 | ||
+ | |||
+ | ==== 监听已读回执回调 ==== | ||
+ | |||
+ | <code java> | ||
+ | EMClient.getInstance().addConversationListener(new EMConversationListener() { | ||
+ | …… | ||
+ | |||
+ | @Override | ||
+ | public void onConversationRead(String from, String to) { | ||
+ | //添加刷新页面通知等逻辑 | ||
+ | } | ||
+ | }); | ||
+ | </code> | ||
+ | 注:onConversationRead中的from和to与消息(EMMessage)中的定义相同。\\ | ||
+ | |||
+ | 会回调onConversationRead的场景:\\ | ||
+ | (1)消息被接收方阅读,且发送了已读回执(conversation ack);\\ | ||
+ | (2)多端多设备登录场景下,一端发送会话已读回执(conversation ack),服务器端会将未读消息数置为0,同时其他端会回调此方法;\\ | ||
+ | |||
+ | ==== 最佳实践 ==== | ||
+ | 推荐使用方案为会话已读回执(conversation ack)+[[im:android:basics:message#消息已读回执|单条消息已读回执(read ack)]]结合实现,可减少发送read ack消息量。\\ | ||
+ | (1)未启动聊天页面的情况下,有未读消息,点击进入聊天页面,调用会话已读回执(conversation ack);\\ | ||
+ | (2)已经启动聊天页面内的情况下,接收到消息,即发送单条消息已读回执 (read ack) ,具体实现可参考:[[im:android:basics:message#发送已读回执消息|发送 read ack 消息]]。\\ | ||
===== 分页获取历史消息记录 ===== | ===== 分页获取历史消息记录 ===== | ||
行 380: | 行 598: | ||
} | } | ||
</code> | </code> | ||
- | ===== 获取所有会话 ===== | + | ===== 获取本地所有会话 ===== |
<code java> | <code java> | ||
Map<String, EMConversation> conversations = EMClient.getInstance().chatManager().getAllConversations(); | Map<String, EMConversation> conversations = EMClient.getInstance().chatManager().getAllConversations(); | ||
</code> | </code> | ||
如果出现偶尔返回的conversations的sizi为0,那很有可能是没有调用''EMClient.getInstance().chatManager().loadAllConversations()'',或者调用顺序不对,具体用法请参考[[30androidsdkbasics#登录|登录]]章节。 | 如果出现偶尔返回的conversations的sizi为0,那很有可能是没有调用''EMClient.getInstance().chatManager().loadAllConversations()'',或者调用顺序不对,具体用法请参考[[30androidsdkbasics#登录|登录]]章节。 | ||
- | | + | ===== 从服务器获取会话列表 ===== |
+ | |||
+ | ''该功能需联系商务开通,开通后,用户默认可拉取 7 天内的 10 个会话(每个会话包含最新一条历史消息),如需调整会话数量请联系环信商务经理(您可以在环信通讯云管理后台首页,扫描二维码联系您的商务经理)。'' | ||
+ | |||
+ | 建议此 API 在首次安装应用时或者本地没有会话的时候调用,其他时候使用本地的会话 API 即可。 | ||
+ | |||
+ | 使用该功能需要联系您的商务经理进行开通。(您可以在环信通讯云管理后台首页,扫描二维码联系您的商务经理) | ||
+ | <code> | ||
+ | EMClient.getInstance().chatManager().asyncFetchConversationsFromServer(new EMValueCallBack<Map<String, EMConversation>>() { | ||
+ | @Override | ||
+ | public void onSuccess(Map<String, EMConversation> value) { | ||
+ | // 获取会话成功后的处理逻辑 | ||
+ | } | ||
+ | @Override | ||
+ | public void onError(int error, String errorMsg) { | ||
+ | // 获取会话失败处理逻辑 | ||
+ | } | ||
+ | }); | ||
+ | </code> | ||
===== 删除会话及聊天记录 ===== | ===== 删除会话及聊天记录 ===== | ||
行 418: | 行 655: | ||
</code> | </code> | ||
+ | ===== 更新消息到 SDK 本地数据库 ===== | ||
+ | |||
+ | <code java> | ||
+ | /** | ||
+ | * 更新消息到 SDK 本地数据库。 | ||
+ | * 消息更新后,会话的 latestMessage 等属性进行相应更新,不能更新消息 ID。 | ||
+ | * | ||
+ | * @param msg 要更新的消息。 | ||
+ | */ | ||
+ | public boolean updateMessage(EMMessage msg) | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ===== 翻译 ===== | ||
+ | |||
+ | 翻译功能使用微软翻译服务实现,用户可将文本翻译为所有微软翻译服务支持的语言,并提供译文存储功能。 | ||
+ | |||
+ | 使用翻译功能需要满足以下条件: | ||
+ | - 已完成环信IM''(3.8.9以上版本)''基本集成,账户登录成功 | ||
+ | - 已创建微软翻译服务资源,并获取到翻译参数,创建过程参见https://docs.microsoft.com/zh-cn/azure/cognitive-services/translator/translator-how-to-signup | ||
+ | |||
+ | 使用过程如下: | ||
+ | - 翻译模块初始化 | ||
+ | - 获取支持的语言/翻译文本消息 | ||
+ | |||
+ | ==== 翻译模块初始化 ==== | ||
+ | |||
+ | 需要将创建微软翻译资源生成的参数(subscriptionKey、endpoint、location)设置到SDK中并初始化,调用如下 | ||
+ | <code> | ||
+ | EMTranslateParams params = new EMTranslateParams(subscriptionKey, endpoint, location); | ||
+ | |||
+ | EMClient.getInstance().translationManager().init(params); | ||
+ | </code> | ||
+ | |||
+ | ==== 获取翻译服务支持的语言 ==== | ||
+ | SDK支持所有微软翻译服务支持的语言,获取支持的语言的过程如下: | ||
+ | <code> | ||
+ | //获取到支持的翻译语言 | ||
+ | List<EMLanguage> emLanguageList = EMClient.getInstance().translationManager().getSupportedLanguages(); | ||
+ | </code> | ||
+ | |||
+ | ==== 文本翻译 ==== | ||
+ | 设置完翻译参数后,用户可以调用消息翻译接口,进行翻译。每一条翻译信息,都有一个所属的会话conversationId,相当于译文所属的分组。翻译调用过程如下: | ||
+ | <code> | ||
+ | EMClient.getInstance().translationManager().translate("msgId", | ||
+ | "conversationId", | ||
+ | "要翻译的文本内容", | ||
+ | "en-us", | ||
+ | new EMValueCallBack<EMTranslationResult>() {}); | ||
+ | </code> | ||
+ | |||
+ | 翻译成功之后,SDK会将译文存储到本地数据库。用户可根据译文的msgId从数据库获取译文,不存在则返回空。获取过程如下: | ||
+ | <code> | ||
+ | EMTranslationResult result = EMClient.getInstance().translationManager().getTranslationResult("msgId"); | ||
+ | </code> | ||
+ | |||
+ | ==== 退出 ==== | ||
+ | 当账户退出时,需要清理缓存中当前账户的译文信息,需要调用如下接口 | ||
+ | <code> | ||
+ | EMClient.getInstance().translationManager().logout(); | ||
+ | </code> | ||
+ | |||
+ | ==== 进阶 ==== | ||
+ | |||
+ | SDK会将译文信息保存到本地数据库,当保存的译文太多时,会数据库文件增大,打开数据库变慢,因此需要定期进行清理。 | ||
+ | |||
+ | SDK提供了以下三种清理方式 | ||
+ | * 按会话清理译文 | ||
+ | 按会话清理译文方式如下: | ||
+ | <code> | ||
+ | EMClient.getInstance().translationManager().removeResultsByConversationId("conversationId"); | ||
+ | </code> | ||
+ | |||
+ | * 按消息Id清理译文 | ||
+ | 按消息清理译文方式如下: | ||
+ | <code> | ||
+ | EMClient.getInstance().translationManager().removeTranslationResult("msgId"); | ||
+ | </code> | ||
+ | |||
+ | * 清除所有译文 | ||
+ | 清理所有译文方式如下: | ||
+ | <code> | ||
+ | EMClient.getInstance().translationManager().clearTranslations(); | ||
+ | </code> | ||
===== Demo 及 SDK 下载 ===== | ===== Demo 及 SDK 下载 ===== |