环信easeui集成:坑总结2018
环信EaseUI 集成,集成不做描述,看文档即可,下面主要谈一些对easeui的个性化需求修改。
该篇文章将解决的问题:
1、如何将App用户体系的用户名和用户头像 显示于环信的easeui
2、如何从library中调用app中的方法?
3、easeui头像都是方形的,如果修改为圆型显示?
4、环信用户注册问题:环信用户注册需要交给服务器注册用户的同时去注册
5、环信登录和注销sdk的使用在App 客户端实现,同步于App用户的登录和退出
6、第一次会话发起的时候,此时发消息的和收消息的用户的数据可能不在数据库中存在,需要在这个情景之下单独先进行双方的数据存储
7、创建群聊方法失败
8、群聊功能,能接受到消息,但是发送消息发不出去
9、会话界面只有点击事件,没有长按点击事件(没有删除操作,需要自行添加长按弹对话框删除操作)
10、easeui 7.0+ 8.0+ 调用会话拍照功能,崩溃
11、easeui 点击对方的视频消息,崩溃问题
--------------------------------------------------------------------------------------------------------------------
一、如何将App用户体系的用户名和用户头像 显示于环信的easeui
这个问题是所有人都想解决的,集成easeui之后 ,虽然大部分功能给我们做好了,但是他是显示的环信用户体系的用户名和默认的头像。
这个用户名是唯一的,官方提供了两种方式来解决。这里我们使用用户发送消息携带扩展信息的方式来实现。
首先看一下环信的用户体系,用户名(唯一值,easeui中显示的用户名就是他,实际上,我们自己数据库的用户体系中,就把用户的唯一id作为环信的用户名)
环信的用户名 == 后台数据库的id , 目的保证唯一值,区分用户信息
App端 需要一个数据库,每一个记录有三个字段: id ,userName, userAvatar
实现思路:
1、发送消息的时候(一般是当前登录用户,取名用户A) ,将项目后台用户A的id、头像url和用户名字符串作为消息的扩展属性一并发送出去
找到EaseChatFragment文件
大致看一下,该行数范围内的代码,很明显是一个个发送各种类型消息的方法,方法内最后都调用了sendMessage()方法,
显然我们需要在sendMessage()方法内 给 消息(message) 添加扩展属性即可 ,如下图
添加了932-935行代码,实现了当app当前登录用户每次发消息(不管什么类型的消息)都会添加3个扩展属性,分别为发出人的用户名,用户头像,用户id
(注意,这个id要在自己的服务器数据里是唯一的,一个用户一个id,用时要求后端开发人员在环信用该id在环信用户体系里作为唯一的用户名,保证自己服务器里一个用户对于环信用户体系里的一个用户)
总结:
第一步,给每个发出去的消息添加3个扩展属性
2、发送方处理好了,只需要给每个发出去的消息添加3个扩展属性即可,接下来就是收消息方的处理
这里每个用户大致有3个主要界面,会话历史界面,联系人界面,单聊窗口界面。
其中会话历史列表界面和联系人界面类似,下面只以会话历史列表界面为例,实现用户头像和用户名的显示
会话历史界面对应的是EaseConversationListFragment界面。
阅读下代码,里面有一个refresh()方法,很现实就是更新列表的方法。
注意的是,该fragment里面是没有监听消息更新的listener,则第一步先根据文档在该fragment里面添加一个消息监听
同时,注册和注销监听
仔细看一个EMMessageListener 里面有一个onMessageReceived(List<Message> message){}回调
很显然,当有消息收到的时候,会执行该方法回调,同时把消息数据返回,注意这里的消息是一个集合的消息数据
结合第一步发出去的每一个消息都带有发送人的用户名,用户头像,用户唯一id 三个信息,则这里只需要把三个信息从每一个消息message里面提取出来即可
代码很简单,注意这里需要用到数据库的知识,我这里使用的是 greendao , 关于数据库的学习这里就不说了,不会的童鞋可以自行去学习
总结:
第二步 就是一个获取每一个消息中的扩展属性,知道这个每一条消息是哪个用户发来的,他的用户名用户头像用户唯一id都可以获取到,然后存储到数据库中
3、上面两步很明显了, 一个是告诉对方 我叫什么、我的头像信息、我的唯一id,一个是接收方,得到每一个消息的扩展属性进行数据库存储。
该流程下第三步就很明显了,就是把存储的数据库信息中获取消息所属用户id的头像和名字 显示在界面上即可(id作为唯一标准)。
①、以会话历史列表界面(EaseConversationListFragment)为例,联系人界面类似
找到那行关键代码:refresh()
handler发送了一个消息,继续找对该消息的处理
很显然,当有消息来的时候,先清空消息列表,然后加载当前消息,刷新listview
看一下conversationListView.refresh()做了什么? ctrl+鼠标左键点击该方法代码进入了 EaseConversationList.java
依旧是handler发送一个消息,继续查询对该消息的处理
最后定位到了adapter.notifyDataSetChanged(),刷新列表 ,定位到EaseConversationAdapter
总结一下,当有新消息来的时候,刷新适配器。
到这里很显然知道该怎么做了,刷新适配器的时候,更改ui即可了
两个if一个else,只需要改else里面部分即可,为啥? 看注释
①、从数据库中根据id获取用户的头像和昵称
如果数据库中没有 ,则用默认的昵称和头像
如果数据库中油 ,则显示,注意,
可以看出原来easeui显示的用户名是环信系统里面的用户名,实际上我们把它作为数据库的id,用该id对应的用户名来显示
显示用户名改为:
②、用户名很简单,把原本显示id的改为显示id对应的用户名字符串的即可
头像呢,定位到EaseUserUtils.setUserAvatar()方法,如下,是easeui原来的使用方式,可以看到都用了一个默认的图片来显示头像
则我们只需要对应在EaseUserUtils里面写一个定制的显示头像的方法 , 将第二个参数 把从数据库对应id取出的记录中的头像url替换,显示
注意,这里Glide的使用,添加了一个.dontAnimate()的使用,用于解决特定情况下第一个不会正常显示图片的情况,算是一个小bug,可根据自身情况添加。
总结:想要在会话历史列表显示实际的头像和用户名 只需要在list对应的adapter修改显示ui的部分代码即可。
4、还剩一个关键的界面,将头像和用户名显示出来,就是会话界面 EaseChatFragment
这个界面需要修改的部分:
①标题,修改为聊天对象的用户名,默认是环信用户体系中聊天用户的用户名,即数据库存的三个扩展属性的id
②发送的消息,即app当前用户发出去的item的头像和用户名,右侧部分
③接受的消息,即app其他用户发过来的item的头像和用户名,左侧部分
下面按顺序解决,
先定位到聊天界面的layout : ease_fragment_chat.xml
如上图,就几个view
很显然,EaseTitleBar 就是聊天界面上的标题
其他,EaseChatMessageList是聊天item的列表
主要修改这两处view的使用
ctrl+鼠标左键定位到EaseTitleBar这个自定义控件位置
在ctrl+鼠标左键点击EaseTitleBar看一下这个控件哪里有用到
跟聊天有关,那很显然就是EaseBaseFragment了,查看一下该文件代码,这个fragment是一个抽象类,有两个方法initview setUpView ,而EaseChatFragment继承了该类
则再回到easeChatFragment里面 查询一下setUpView 和 initView的使用
到这里就很显然了, 这便是单聊情况下的if
easeui原代码是灰色注释掉的部分,可以看到titleBar显示的是用户的用户名,即环信用户体系中的用户名,而我们把他作为id,唯一值
所以在这里还是根据这个id来去数据库中找寻id对应的用户名 setTitle()进去即可,修改聊天界面标题为对方用户名就是这么简单。
接下来是修改聊天界面的发送方和接收方的头像问题。
这个具体找到代码的思路就不介绍了,比较麻烦,直接定位到想要代码吧
这里就是各种类型的消息的item的自定义控件,都继承自EaseChatRow类
然后研究一下EaseChatRow类 ,发现了关键代码
比较容易看懂,当消息是发出去的时候,调用了一个现实头像的方法,当消息是接收的时候,定义了一个现实头像和用户名的方法
那解决方法,就是从该处在数据库中根据id获取到头像和用户名的数据显示即可。
思路如此,不在细讲
二、如何从library中调用app中的方法?
当依赖easeui的时候,是用import module的形式导入的,所以主程序是可以调用easeui类库中的类和方法,但是反之不行
当数据库操作的时候,发现该问题,解决办法就是反射调用,具体查询相关文章
三、easeui头像都是方形的,如果修改为圆型显示?
找一个用到显示头像的xml代码
可以看到easeui使用了一个自定义控件来显示EaseImageView
查看该控件源码:
发现
说明该控件的shapeType属性是来控制图片是方形显示还是圆形显示的。
查询源码发现init()方法对该属性进行了初始话,默认值为0 ,如果想圆形显示,则改为1即可
如此一来,不该显示图片的控件,不该每一个调用控件的自定义属性 即可实现统一圆形显示。
其他注意点:
1、环信用户注册需要交给服务器注册用户的同时去注册
2、环信登录和注销sdk的使用在App 客户端实现,同步于App用户的登录和退出
3、第一次会话发起的时候,此时发消息的和收消息的用户的数据可能不在数据库中存在,需要在这个情景之下单独先进行双方的数据存储
4、上面讲到一个接收到新消息的回调方法 onMessageReceived
会有一种情况。B用户尚未登录APP, A用户给B用户发了消息(两个用户之间是第一次会话,并且是A给B发起的会话,也就是说B用户那边是没有数据库存储A用户的三个信息的),B用户登录消息之后 会有消息列表,但是因为没有执行
onMessageReceived 方法,导致没有对A用户的消息中的扩展数据进行数据库存储,所以会导致B用户这边会话列表中A用户的头像和用户名显示不出,解决办法 定位到EaseConversationListFragment类中的 loadConversationList 方法
查看源码得知会话列表刷新的时候都会执行,那就在这个方法中对所有的消息的扩展字段进行数据库存储,且只有第一次创建该fragment的时候才执行存储
onCreate()中
boolean isLoadData = false; // 是否已经缓存了数据 用于界面刚登陆的时候 对之前接受到的数据的处理
--------------------------------------------------------------------------------------------------------------------------------------------------------
5.、创建群聊方法失败
报303 错误,
解决办法,这个方法的使用需要在子线程中进行,不可以在主线程进行
所以放到Thread里面即可
6、群聊功能,能接受到消息,但是发送消息发不出去
经检查:
当点击会话列表 群组item进入会话界面的时候,EaseChatFragment.java 中 的setUpView方法执行了 if(chatType == EaseConstant.CHATTYPE_SINGLE)
为什么点击群组item进入的类型是单聊的type, 往上查询chatType怎么来的
显然是从Activity中获取到的,同时还从Activity中获取到了 toChatUsername 的值
继续往上查询 EaseChatActivity
发现这里进行了setArguments方法,显然这里不是数据最开始获取的地方,继续查,就是进入到EaseChatActivity的intent跳转调用了
发现了intent传递了 但是没有传递
而显然一直类型为默认类型EaseConstant.CHATTYPE_SINGLE
导致群聊进入会话界面的类型是单聊
所以intent进入EaseChatActivity的时候,将 一并传递
如下:
Log日志:
发现type是GroupChat也就是字符串类型,但是接受的时候是int类型
找到EMConversation.class类
还有EaseConstant.class类
解决办法,intent打开EaseChatActivity.class 的时候 传递相应的int值即可
7、会话列表item长按事件
easeui默认是没有会话列表item长按事件的,体验上就是会话列表没有删除操作
所以需要我们自行给会话列表添加一个item长按事件监听
解决办法:
找到EaseConversationListFragment.java
这个fragment是会话界面
找到setUpView()方法,第三行
很明显这里是单点事件的接口回调
当然,如果长按事件需要在该fragment处理的,则直接添加长按点击事件
如果想和单点事件一样,则需要仿照单点做一个接口回调,这里不再叙述。
8、easeui 7.0+ 8.0+ 调用会话拍照功能,崩溃
easeui调用相机代码本身没有适配7.0+ 8.0+ 机型 , 需要自己适配一下
解决方案:Android项目实战(四十九):Andoird 7.0+相机适配
具体调整代码:
找到EaseChatFragment文件,这个是会话界面相关
找到 selectPicFromCamera方法,调用相机方法
更改代码如下:
/**
* capture new image
*/
protected void selectPicFromCamera() {
if (!EaseCommonUtils.isSdcardExist()) {
Toast.makeText(getActivity(), R.string.sd_card_does_not_exist, Toast.LENGTH_SHORT).show();
return;
} cameraFile = new File(PathUtil.getInstance().getImagePath(), EMClient.getInstance().getCurrentUser()
+ System.currentTimeMillis() + ".jpg");
//noinspection ResultOfMethodCallIgnored
cameraFile.getParentFile().mkdirs();
// 7.0+ 8.0+ 调用相机适配
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
intent.putExtra(MediaStore.EXTRA_OUTPUT,
FileProvider.getUriForFile(getActivity(),"你的包名.fileprovider", cameraFile));
}else {
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile));
}
startActivityForResult(intent, REQUEST_CODE_CAMERA);
}
9、easeui 点击对方的视频消息,崩溃问题
这个问题看日志就知道怎么解决,因为没有在清单文件中注册
解决方法:
AndroidManifest.xml 文件注册 EaseShowVideoActivity
<activity android:name="com.hyphenate.easeui.ui.EaseShowVideoActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="portrait"></activity>
andoird7.0+ 机型的适配
查找EaseCompat.java 文件
会有如下代码适配7.0+ 视频播放的
这里要注意 easeui自带写的是fileProvider 和 自己写的AndroidManifest.xml 中的7.0+适配代码的 authorities 值是否一致,
按文章上面描述的方法写的是fileprovider , P小写,注意 要改成一致,即
否则报错:
-------------------------------------------------------------------------------------------------------------------------------------------------
有问题欢迎加Android群探讨。。
环信easeui集成:坑总结2018的更多相关文章
- 环信easeui集成:坑总结2018(二)
环信EaseUI 集成,集成不做描述,看文档即可,下面主要谈一些对easeui的个性化需求修改. 该篇文章将解决的问题: 1.如何发送视频功能 2.未完待续.. ------------------- ...
- 环信EaseUI集成错误 Unknown type name 'NSString' NSLocalizedString
环信集成本来认为很简单的,有现成的UI,照着文档直接傻瓜操作就行,没曾想聊天记录不能长时间保存,于是乎就有了这篇记录环信坑的笔记 在下载的环信的SDK时候里面会有两个包,一个完整版的,一个简洁版的,导 ...
- 李洪强iOS开发之-环信03_集成 SDK 基础功能
李洪强iOS开发之-环信03_集成 SDK 基础功能 集成 SDK 基础功能 在您阅读此文档时,我们假定您已经具备了基础的 iOS 应用开发经验,并能够理解相关基础概念. SDK 同步/异步方法区分 ...
- 环信SDK集成
利用环信SDK可以实现即时通讯,但在集成的过程中碰到了不少的坑. 注意 选择项目路径,这里以最新版环信demo为例 注意:环信的ChatDemoUI这个demo里边因为研发的同事为了照顾老版本的And ...
- laravel 框架接入环信遇到的坑(-)
在脚本中执行判断user表中是否注册环信时,报错: “请求错误:service_resource_not_found Service resource not found ” // 判断环信是否已经 ...
- iOS 环信集成项目应用
环信iOS端3.0版本集成记录--聊天界面篇 环信离线推送证书... 1,环信处在后台的时候,消息的接收与推送 离线发推送 配置属性 EMCallOptions *options = [[EMClie ...
- 环信集成 2---基于环信Demo3.0,实现单聊功能
这几天在做环信,所以把环信相关的东西拿过来,做个系统点的东西 注意: 这里Demo集成的是带有实时语音功能的(libEaseMobClientSDK.a). 环信库是直接拖拽EaseMobSDK文件夹 ...
- apicloud 环信总结
点击链接先查看一下apicloud 环信的文档 https://docs.apicloud.com/Client-API/Open-SDK/easeChat 文档中写了很多,但官方给的文档还是有问题, ...
- iOS 环信集成问题(连文档都不说明的坑。。)
首先,关于环信SDK的下载和一些依赖库的添加,在此我就不做详细介绍,(http://www.easemob.com/download/im)附上环信官网文档,可以看一下,上面都可以下载,也有相关配置介 ...
随机推荐
- 1 分钟教会你用 Spring Boot 发邮件
Spring Boot 提供了一个发送邮件的简单抽象,使用的是下面这个接口. org.springframework.mail.javamail.JavaMailSender Spring Boot ...
- Linux(CentOS)下安装Elasticsearch5.0.0
一.ES5.0解压安装到Windows之后(可能)需要进行的设置: 1.如果不设置,直接运行elasticsearch.bat 文件 ,会报错: 2.解决方式 调节 conf/jvm.options ...
- 13 Tensorflow机制(翻译)
代码: tensorflow/examples/tutorials/mnist/ 本文的目的是来展示如何使用Tensorflow训练和评估手写数字识别问题.本文的观众是那些对使用Tensorflow进 ...
- Xpath 获取html文档的标签
1.html page content: <div class="mnr-c _yE"> <div class="_kk _wI">In ...
- go跨平台编译
go语言支持直接编译不同系统的可执行程序,例如可以直接在mac上可以直接编译linux的执行程序 支持的环境变量 GOOS:目标可执行程序运行操作系统,支持 darwin,freebsd,linux, ...
- 系统不支持WP开发
好伤心,,,系统不支持WP开发... 买的ThinkPad S5 自带的win8,既不属于专业版,也不属于家庭版,,不属于各种版本. 其他条件都满足了.. 难道我要还系统吗??
- python列表类型
列表类型简介 列表类型是一个容器,它里面可以存放任意数量.任意类型的数据. 例如下面的几个列表中,有存储数值的.字符串的.内嵌列表的.不仅如此,还可以存储其他任意类型. >>> L ...
- OJ:重载 << 运算符
Description 补足程序,使得下面程序输出的结果是: ****100 #include <iostream> #include <string> using names ...
- linux内核源码目录结构分析
原文地址 /arch.arch是architecture的缩写.arch目录下是好多个不同架构的CPU的子目录,譬如arm这种cpu的所有文件都在arch/arm目录下,X86的CPU的所有文件都在a ...
- linux的文档和目录结构
在Linux底下,所有的文件与目录都是由根目录开始,是目录与文件的源头,然后一个个的分支下来,如同树枝状,因此称为这种目录配置为:目录树. 目录树的特点是什么呢? 目录树的起始点是根目录(/,root ...