工作篇 之 简单聊下有关环信的 “坑” ...
LZ-Says:相遇,相知,相恋,争执,平淡,压抑,愤懑,该画上句号了。
前言
环信,Enmmm,牛逼,懵 ing ~!
最近这段时间一直围绕环信,在使用的过程中,遇到很多很多问题,自己都感觉蒙圈,烦躁。
还好,明远小哥哥很 nice,点拨给力,到位,赞一个~!
明天要开启新的征程了,希望一切顺利,加油哦~!
今天简单整理下,LZ 所经历到的环信之 “坑” ~~~
Enmmm,环信,你好
首先,列举本文将要描述的内容简述:
查询本地消息历史记录
清空聊天记录保留会话
显示 “输入中。。。”
接着,我们进行逐步说明。
一、查询本地消息历史记录
搜索 API 文档,得出环信官方提供了如下不同类型接口:
经过文哥指点,最终确定使用如下类型接口:
原想着很美好,很 easy,分分钟,嗯,开始的代码如下:
List<EMMessage> resultList = mConversation.searchMsgFromDB(mSearchView.getText().toString(),System.currentTimeMillis(),50,null,EMConversation.EMSearchDirection.UP);
。。。
Adapter 更新即可
But,美滋滋的测试的时候,突然发现一个问题,只能搜索 汉字,输入 单个数字 或者 单个字母,则检索出所有数据。 百思不得其解,内心无数的 MMP,无奈下只能提交工单,嗯,工单好。
为环信敬业赞一个,But,回复的是,我们这边没事。
想问问有什么原因导致,嗯,你自己检查下。
咋检查啊,之前好好地,我就是在这个基础加了一个查询本地消息,怎么破?
文档也看了,度娘也扒光了,无招。项目又比较急,怎么办?
找出共性,逐步解决~!
List<EMMessage> resultList = mConversation.searchMsgFromDB(mSearchView.getText().toString(),System.currentTimeMillis(),50,null,EMConversation.EMSearchDirection.UP);
// 1. 创建临时存储 List
List<EMMessage> 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会话,如果需要保留聊天记录,传false
EMClient.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() {@Overridepublic void onResult(boolean confirmed, Bundle bundle) {if (confirmed) {if (conversation != null) {conversation.clearAllMessages();}messageList.refresh();haveMoreData = true;}}}, true).show();
}
看似很美好,But,EaseUI 中对此进行了拦截,不信?截图为证:
Enmmm,嗨皮不?人给你拦截了,哇咔咔。
有的小伙伴说,你把这个干掉不就好了嘛?
嘿嘿嘿,彩蛋还是要自己去发掘的。
这里还是感谢明远老哥指点,模仿类似群加人,群删人发送时,本地插入消息。
So,开始模仿之路,说白了,我们要为我们的 EaseChatRow 新添加另外一种类型。
Step 1:为 EaseChatRow 新增一种类型
public static final String MESSAGE_PLACEHOLDER = "placeholder";
Step 2:创建 EaseChatRow 布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content" />
Step 3:创建 EaseChatRow 实例类
public class EaseChatRowPlaceHolder extends EaseChatRow {public EaseChatRowPlaceHolder(Context context, EMMessage message, int position, BaseAdapter adapter) {super(context, message, position, adapter);}@Overrideprotected void onInflateView() {inflater.inflate(R.layout.ease_row_place_holder, this);}@Overrideprotected void onFindViewById() {}@Overrideprotected void onViewUpdate(EMMessage msg) {}@Overrideprotected void onSetUpView() {}}
Step 4:来,搞个 P
public class EaseChatPlaceHolderPresenter extends EaseChatRowPresenter {@Overrideprotected EaseChatRow onCreateChatRow(Context cxt, EMMessage message, int position, BaseAdapter adapter) {return new EaseChatRowPlaceHolder(cxt, message, position, adapter);}@Overridepublic void onBubbleClick(EMMessage message) {super.onBubbleClick(message);}@Overrideprotected 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);// 设置消息bodycmdMsg.addBody(cmdBody);// 设置要发给谁,用户username 或者群聊groupidcmdMsg.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:实现监听
@Overridepublic void onInputStatusListener(String inputStatus) {if ("input".equals(inputStatus)) {if (System.currentTimeMillis() - firstTime > time) {sendInputMsg("input");firstTime = System.currentTimeMillis();}} else {sendInputMsg("inputStop");}}
结束
目前而言,LZ 经历的以上问题总结完成,如有遗漏,请指明,谢谢~
剩下的以后遇到再补充吧~
烦
个人公众号
不定期发布博文,最近有点忙,感谢老铁理解,欢迎关注~
参考资料
- Android SDK API Doc:http://docs-im.easemob.com/im/android/sdk/apidoc;
- 删除会话及聊天记录:http://docs-im.easemob.com/im/android/basics/message#删除会话及聊天记录;
- 输入状态提示:http://docs-im.easemob.com/im/other/integrationcases/inputstatus#输入状态提示;
工作篇 之 简单聊下有关环信的 “坑” ...相关推荐
- Esp8266 进阶之路25【高级篇】深聊下esp8266的串口 Uart 通讯中断编程,为您准备好了 NONOS 版本 和 RTOS 系统的串口驱动文件。(附带Demo)
本系列博客学习由非官方人员 半颗心脏 潜心所力所写,不做开发板.仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 序号 SDK版本 内容 链接 1 nonos2.0 搭建 ...
- android 环信集成,Android Studio下的环信即时通讯简单集成
环信即时通讯云是全球最大的即时通讯云 PaaS 平台,可以快速实现APP的即时通讯的功能,官方的DEMO是基于Eclipse开发的,对于新版本的Android Studio支持不太好,下面就简单说一下 ...
- Android环信爬坑指北(二)头像昵称好友备注显示
在上一篇文章中提到了要在初始化的时候,设置用户信息提供者类--EaseUserProfileProvider,用以获取用户信息.下面我们来看一下 EaseUserProfileProvider 是 ...
- 简单聊下STM32F103的GPIO
GPIO是芯片和外界沟通的桥梁,GPIO有很多模式,不同的模式有不同的配置,应用于不同的场合. STM32F103系列的I/O引脚共有8种工作模式, 输入模式有四种 浮空输入 上拉输入 下拉输入 模拟 ...
- 简单聊下中台概念与发展
什么是中台 中台可以视作是支持多个前台业务中具有公共业务属性的能力组织. 所以他有组织+系统两个层面的事情.需要有个自运营的组织,对外提供的是抽象的服务. 钟华老师说:中台是将企业核心能力以服务化形式 ...
- 简单聊下STM32F103的时钟
对于芯片而言,电源和时钟是缺一不可的. 电源为芯片提供能量,时钟则提供时间基准,芯片好按照这个tick依次执行指令. STM32F103是一款性价比很好的芯片,它的时钟树长这样: 它有4个时钟源,不同 ...
- 简单聊下STM32F103的串口
串口是单片机嵌入式必不可少的外设,它上手简单,使用方便,很受小伙伴的欢迎. 用STM32CubeMX体验下STM32F103的串口,硬件平台采用百问网STM32F103mini开发板. 生成的一些代码 ...
- 简单聊下5G与V2X
V2X是将车辆与一切事物相连接的新一代信息通信技术,其中V代表车辆,X代表任何与车交互信息的对象,包括车.人.交通路侧基础设施和网络.V2X是通过专用通信协议和频谱实现一定区域内.一定条件下的数据互通 ...
- 简单聊下STM32F103的中断
中断 当cpu在执行指令时,遇到一些突发状况,不得不先处理这些突发状况,处理完毕后再返回原来执行指令处继续执行,这里的突然状况被称为中断或异常. 中断示意图如下: STM32F103的中断系统很强大, ...
最新文章
- C#中静态方法的运用和字符串的常用方法(seventh day)
- 在Win7下利用VirtualBox和Vagrant安装Docker
- tensorflow随笔-文件数据读取
- [蓝桥杯][基础练习VIP]芯片测试-思维
- IDEA上Debug调试全流程
- 雷军被重新任命为金山软件董事会副主席
- 第41章 实施数据库审计
- HDU 5912 Fraction (2016-ccpc-长春)
- spring催办业务_业务后台系统之流程设计
- node.js学习之npm 入门 —8.《怎样创建,发布,升级你的npm,node模块》
- Java语言程序设计基础篇第10版第5章习题答案
- 毕设-周报-20150520
- Spring常用注解
- Python打包exe文件并换图标【最强版教程】
- 操作系统 - 沙箱(sandboxing)技术
- 详解统计套利交易系统模型
- 2022年2月语音合成(TTS)和语音识别(ASR)论文月报
- 我们采访了三位学生:他们写代码、95 后、来自大陆和台湾
- 黑帽SEO关键字堆砌的原理以及作用
- 数据科学家:为什么我要离职……