登录 立即注册
安币:

安卓巴士 - 安卓开发 - Android开发 - 安卓 - 移动互联网门户

查看: 234|回复: 0

工作篇 之 简单聊下有关环信的 “坑” ...

[复制链接]

102

主题

317

帖子

910

安币

代码手工艺人

Rank: 4

中级博主QQ达人最佳新人热心会员原创勋章明星会员突出贡献签到达人优秀版主资源达人推广达人

QQ
发表于 2019-2-3 09:40:01 | 显示全部楼层 |阅读模式
如果对本篇文章感兴趣,请前往,原文地址:http://www.apkbus.com/blog-904057-79484.html

> LZ-Says:相遇,相知,相恋,争执,平淡,压抑,愤懑,该画上句号了。 ![图片描述](/data/attachment/album/201902/02/120108l30ku9sge3bzebk9.gif)### 前言环信,Enmmm,牛逼,懵 ing ~!最近这段时间一直围绕环信,在使用的过程中,遇到很多很多问题,自己都感觉蒙圈,烦躁。还好,明远小哥哥很 nice,点拨给力,到位,赞一个~!明天要开启新的征程了,希望一切顺利,加油哦~!今天简单整理下,LZ 所经历到的环信之 **“坑”** ~~~### Enmmm,环信,你好首先,列举本文将要描述的内容简述:-  查询本地消息历史记录-  清空聊天记录保留会话-  显示 “输入中。。。”接着,我们进行逐步说明。#### 一、查询本地消息历史记录搜索 API 文档,得出环信官方提供了如下不同类型接口:![在这里插入图片描述](https://img-blog.csdnimg.cn/20181111220553111.png)经过文哥指点,最终确定使用如下类型接口:![在这里插入图片描述](https://img-blog.csdnimg.cn/20181111220733996.png)原想着很美好,很 easy,分分钟,嗯,开始的代码如下:```List resultList = mConversation.searchMsgFromDB(        mSearchView.getText().toString(),        System.currentTimeMillis(),        50,        null,        EMConversation.EMSearchDirection.UP);。。。Adapter 更新即可```But,美滋滋的测试的时候,突然发现一个问题,**只能搜索 汉字,输入 单个数字 或者 单个字母,则检索出所有数据。** 百思不得其解,内心无数的 MMP,无奈下只能提交工单,嗯,工单好。为环信敬业赞一个,But,回复的是,我们这边没事。想问问有什么原因导致,嗯,你自己检查下。咋检查啊,之前好好地,我就是在这个基础加了一个查询本地消息,怎么破?文档也看了,度娘也扒光了,无招。项目又比较急,怎么办?**找出共性,逐步解决~!**```List resultList = mConversation.searchMsgFromDB(        mSearchView.getText().toString(),        System.currentTimeMillis(),        50,        null,        EMConversation.EMSearchDirection.UP);// 1. 创建临时存储 ListList tempList = new ArrayList();mMessageIDList = new ArrayList();// 2. 循环遍历 进行手动过滤for (int i = 0; i < resultList.size(); i  ) {    if (resultList.get(i).getBody() instanceof EMTextMessageBody) {        if (((EMTextMessageBody) resultList.get(i).getBody()).getMessage().contains(mSearchView.getText().toString())) {            tempList.add(resultList.get(i));        }    }}// 3. 将最后过滤后的 List 赋值到 RecyclerView 中的 List 并进行 notify 即可if (mMessageList == null) {    mMessageList = tempList;} else {    mMessageList.clear();    mMessageList.addAll(tempList);}```LZ 实属无奈,如有其他小伙伴也曾经遇到过,并完美解决,还望告知~ #### 二、清空聊天记录保留会话这个,真的比较坑了。需求就是和小题目一样,聊天记录清空且会话不能删除。好,那我们开始逐步解决这个问题,官网显示,清除聊天记录需要调用如下 API:```// 删除和某个user会话,如果需要保留聊天记录,传falseEMClient.getInstance().chatManager().deleteConversation(username, true);// 删除当前会话的某条聊天记录EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username);conversation.removeMessage(deleteMsg.msgId);```二话不说,拷贝进来再说。测试后,发现会话也被移除了,咋整,度娘呗。经过了度娘以及工单后,发现了如下方法:```/** * clear the conversation history */protected void emptyHistory() {    String msg = getResources().getString(R.string.Whether_to_empty_all_chats);    new EaseAlertDialog(getActivity(), null, msg, null, new EaseAlertDialog.AlertDialogUser() {        @Override        public void onResult(boolean confirmed, Bundle bundle) {            if (confirmed) {                if (conversation != null) {                    conversation.clearAllMessages();                }                messageList.refresh();                haveMoreData = true;            }        }    }, true).show();}```看似很美好,But,EaseUI 中对此进行了拦截,不信?截图为证:![在这里插入图片描述](https://img-blog.csdnimg.cn/20181111230617191.png)Enmmm,嗨皮不?人给你拦截了,哇咔咔。有的小伙伴说,你把这个干掉不就好了嘛?嘿嘿嘿,彩蛋还是要自己去发掘的。这里还是感谢明远老哥指点,模仿类似群加人,群删人发送时,本地插入消息。So,开始模仿之路,说白了,我们要为我们的 EaseChatRow 新添加另外一种类型。**Step 1:为 EaseChatRow 新增一种类型**```public static final String MESSAGE_PLACEHOLDER = "placeholder";```**Step 2:创建 EaseChatRow 布局**``````**Step 3:创建 EaseChatRow 实例类**```public class EaseChatRowPlaceHolder extends EaseChatRow {    public EaseChatRowPlaceHolder(Context context, EMMessage message, int position, BaseAdapter adapter) {        super(context, message, position, adapter);    }    @Override    protected void onInflateView() {        inflater.inflate(R.layout.ease_row_place_holder, this);    }    @Override    protected void onFindViewById() {    }    @Override    protected void onViewUpdate(EMMessage msg) {    }    @Override    protected void onSetUpView() {    }}```**Step 4:来,搞个 P**```public class EaseChatPlaceHolderPresenter extends EaseChatRowPresenter {    @Override    protected EaseChatRow onCreateChatRow(Context cxt, EMMessage message, int position, BaseAdapter adapter) {        return new EaseChatRowPlaceHolder(cxt, message, position, adapter);    }    @Override    public void onBubbleClick(EMMessage message) {        super.onBubbleClick(message);    }    @Override    protected void handleReceiveMessage(EMMessage message) {        if (!message.isAcked() && message.getChatType() == EMMessage.ChatType.Chat) {            try {                EMClient.getInstance().chatManager().ackMessageRead(message.getFrom(), message.getMsgId());            } catch (HyphenateException e) {                e.printStackTrace();            }            return;        }        EaseDingMessageHelper.get().sendAckMessage(message);    }}```完成了以上几步,接下来,则是要为 EaseChatRow 指明我们定义的消息体类型即可。**Step 5:Adapter 针对特定的类型返回特定的 EaseChatRow****EaseMessageAdapter --> getItemViewType:**```// 清除聊天消息 发送空字符if (message.getBooleanAttribute(EaseConstant.MESSAGE_PLACEHOLDER, false)) {    return message.direct() == EMMessage.Direct.RECEIVE ? MessageAdapterConstant.MESSAGE_TYPE_SENT_PLACE_HOLDER : MessageAdapterConstant.MESSAGE_TYPE_SENT_PLACE_HOLDER;}```**EaseMessageAdapter --> createChatRowPresenter:**```else if (message.getBooleanAttribute(EaseConstant.MESSAGE_PLACEHOLDER, false)) {     presenter = new EaseChatPlaceHolderPresenter();} ```**Step 6:最后,发送一条我们指定类型的消息**```EMClient.getInstance().chatManager().deleteConversation(group.getId(), true);EMClient.getInstance().chatManager().getConversation(group.getId(), EMConversation.EMConversationType.GroupChat, true);// 记得,这边要创建一条发送消息,不然列表会出现小彩蛋 感谢我老哥EMMessage message = EMMessage.createSendMessage(EMMessage.Type.TXT);message.setChatType(EMMessage.ChatType.GroupChat);EMTextMessageBody body = new EMTextMessageBody("");message.setTo(group.getId());message.addBody(body);// 设置当前消息类型message.setAttribute(MESSAGE_PLACEHOLDER, true);message.setAttribute("hxId", SPUtils.get(AppConstant.HXID, "").toString());message.setAttribute("avatar", SPUtils.get(AppConstant.AVATAR, "").toString());message.setAttribute("groupId", group.getId() != null ? group.getId() : "");message.setAttribute("cover", group.getCover() != null ? group.getCover() : "");message.setUnread(false);EMConversation conversation = EMClient.getInstance().chatManager().getConversation(group.getId());conversation.appendMessage(message);```#### 三、显示 “输入中。。。”首先,我们先了解下有关输入状态官网简述:> 监听用户 A 输入状态,一旦有文字输入,就每隔几秒通过透传消息将输入状态发送到聊天接受方 B,B 客户端收到输入状态透传后,提示用户 A 正在输入。 - 用户 A 向用户B 发一条表示输入状态透传消息;- 用户 B 在收到消息后,判断当前是否在与 A 聊天的页面,如果在,显示 A 的输入状态;- 当隔几秒后没有再次收到 A 的输入状态,自动取消显示。>注:**“透传消息”是一种特殊类型的消息,收发双方不会存数据库,同时用户离线时也不会有推送,比较适合配合业务来处理一些功能。** 并且 A 用户不需要不停的向 B 发送消息,可以设置一个时间,判断发送间隔。So,我们这个代码很 Easy。**Step 1:编写我们发送透传消息体**```/** * 自定义时间间隔发送状态消息(单位:ms) */public int time = 2000;/** * 文本框第一次输入内容变化的时间 */public long firstTime = System.currentTimeMillis();/** * 发送输入状态的透传消息 */private void sendInputMsg(String inputState) {        // 这里需要判断    if (chatType == EaseConstant.CHATTYPE_SINGLE) {        EMMessage cmdMsg = EMMessage.createSendMessage(EMMessage.Type.CMD);        // 如果是群聊,需要设置 chattype,默认是单聊        String action;        if ("input".equals(inputState)) {            action = "input";        } else {            action = "stopInput";        }        EMCmdMessageBody cmdBody = new EMCmdMessageBody(action);        // 设置消息body        cmdMsg.addBody(cmdBody);        // 设置要发给谁,用户username 或者群聊groupid        cmdMsg.setTo(toChatUsername);        EMClient.getInstance().chatManager().sendMessage(cmdMsg);    }}```**Step 2:EaseChatMenu 添加监听****这里需要注意,什么时候发送 input,什么时候发送 inputStop。**```if (TextUtils.isEmpty(s)) {    // 发送 inputStop 状态    listener.onInputStatusListener("inputStop");} else {    // 发送 input 状态    listener.onInputStatusListener("input");}```**Step 3:实现监听**``` @Override public void onInputStatusListener(String inputStatus) {     if ("input".equals(inputStatus)) {         if (System.currentTimeMillis() - firstTime > time) {             sendInputMsg("input");             firstTime = System.currentTimeMillis();         }     } else {         sendInputMsg("inputStop");     } }```### 结束目前而言,LZ 经历的以上问题总结完成,如有遗漏,请指明,谢谢~剩下的以后遇到再补充吧~烦### 个人公众号不定期发布博文,最近有点忙,感谢老铁理解,欢迎关注~![图片描述](/data/attachment/album/201902/02/120225b2w3ad9uhuv3whga.png)#### 参考资料1. Android SDK API Doc:http://docs-im.easemob.com/im/android/sdk/apidoc;2. 删除会话及聊天记录:http://docs-im.easemob.com/im/android/basics/message#删除会话及聊天记录;3. 输入状态提示:http://docs-im.easemob.com/im/other/integrationcases/inputstatus#输入状态提示;  继续阅读全文



想在安卓巴士找到更多优质博文,可移步博客区

如果对本篇文章感兴趣,请前往,
原文地址:
http://www.apkbus.com/blog-904057-79484.html
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站长推荐

通过邮件订阅最新安卓weekly信息
上一条 /4 下一条

下载安卓巴士客户端

全国最大的安卓开发者社区

广告投放| 广东互联网违法和不良信息举报中心|中国互联网举报中心|下载客户端|申请友链|手机版|站点统计|安卓巴士 ( 粤ICP备15117877号 )

快速回复 返回顶部 返回列表