前言
最近项目需要及时通讯功能,和ios一起选择了环信。因为几年前刚开始工作时第一个app有类似功能用的融云,他们文档加自己理解问题,弄了很久,这次环信还好,几天就将自己想要的效果展示出来了(仅单聊和历史列表)。这里详细记录下集成步骤和继承时自己遇到的一些坑点。(本文使用Kotlin)
主要解决问题:
1.集成步骤
2.环信用户注册失败
3.给消息添加拓展属性
4.修改聊天头像和昵称,将头像改为圆形
5.给历史聊天添加监听
6.历史聊天头像不展示问题
集成步骤:
环信的官方文档写的挺清楚的,这里就不再叙述
集成官网
集成导包可能出现包冲突,需要自己解决冲突
注册,登录,退出登录
环信用户注册失败,不成功
遇到这个问题其实挺郁闷,明明一步一步都是按照官方文档来的呀。(环信提供了示例demo,但是我用的时候出现了问题,就没打开了,要是看了可能不会出现。)
原因:环信注册不能在UI线程中执行,必须用子线程。
示例:(Kotlin)
Thread(
Runnable {
try {
EMClient.getInstance()
.createAccount("${SharedUtil.get().getString(AppSetting.USERID)}", "QWERTYUIOP")//同步方法
//注册成功
}
} catch (e: HyphenateException) { //注册失败会抛出异常HyphenateException
runOnUiThread {
val errorCode = e.errorCode
when (errorCode) {
EMError.NETWORK_ERROR -> Toast.makeText(
this,
resources.getString(R.string.network_anomalies),
Toast.LENGTH_SHORT
).show()
EMError.USER_ALREADY_EXIST -> {
//用户已存在
}
EMError.USER_AUTHENTICATION_FAILED -> Toast.makeText(
this,
"注册失败,权限问题",
Toast.LENGTH_SHORT
).show()
EMError.USER_ILLEGAL_ARGUMENT -> Toast.makeText(
this,
resources.getString(R.string.illegal_user_name),
Toast.LENGTH_SHORT
).show()
else -> Toast.makeText(
this,
"注册失败",
Toast.LENGTH_SHORT
).show()
}
}
}
}).start()
给消息添加拓展属性
我们先看环信的用户体系,环信中有个用户名,唯一,Easeui中显示的用户名就是这里的id。
实现:
发送消息时,将发送消息人A的id,头像,昵称等作为消息的拓展属性一并发送
我们找到聊天Fragment—EaseChatFragment,点击进入EaseChatFragment源码。
我们大致看一下,这很明显是发送消息的一些方法,最终调用的都是sendMessage方法。我们在此sendMessage方法内给消息添加拓展属性即可:
userId,nickName,picUrl,sexId(自己特定的属性)怎样传递到EaseChatFragment中,和示例代码中EaseConstant.EXTRA_CHAT_TYPE和EaseConstant.EXTRA_USER_ID一样,使用Fragment的setArguments方法。
我们找到EaseChatFragment中onActivityCreated,发现了接收chatType和userid的方法。
我依葫芦画瓢在EaseConstant中添加了EXTRA_USER_ID_OTHER,EXTRA_NICKNAME,EXTRA_PIC_URL,EXTRA_SEX_ID,接着在onActivityCreated添加了相关的接收方法:
在你自己的activity或者fragment中,发送这些属性。
注意:我上边上传了两个userId,一个EXTRA_USER_ID原代码就有,一个EXTRA_USER_ID_OTHER是我添加的,为什么要传两个id?如果是A用户给B用户发送信息,第一个EXTRA_USER_ID是指B用户的userId,即用户想要和谁聊天,EXTRA_USER_ID_OTHER是指A用户的userId,即发送消息的A,nickName,picUrl都是发送消息的A的信息,因为要传给sendMessage的拓展消息也是A发送的。
以上是发送拓展属性,接收呢?官方文档有这样一段叙述:
修改聊天头像和昵称,将头像改为圆形
在EaseChatFragment中可以找到设置的痕迹:
接收到消息的onMessageReceived中回传了Message,message中我们可以取到拓展信息并保存。
以历史消息列表EaseConversationListFragment为例:
给EaseConversationListFragment添加EMMessageListener:收到消息后将所有的id和拓展信息存到了一个map,并刷新,refresh()方法是刷新。这样我们在sendMessage()时发送拓展信息,监听listener中接收并保存下来,到想用的时候就能用啦!
在initView中添加监听事件
EMClient.getInstance().chatManager().addMessageListener(listener);
在onDestroy方法中移除监听
上边存储我用的静态存储方式,你也可以用数据库等。
接收后我们要找到聊天界面、历史消息等等页的设置头像的地方,以历史聊天列表EaseConversationListFragment为例:
我们找到了更新方法refresh()
继续
点击conversationListView.refresh()方法。顾名思义,conversationListView是会话列表
继续,这里看到了一个adapter,找到adapter方法啦
在EaseConversationAdapter的getView方法中,我们可以找到单聊的设置头像,昵称的代码:
把它修改成自己的逻辑,我们已经将数据存储下来,只要将userId对应的昵称和头像,然后设置。我们看到下边有glide加载图片的方法。使用circleCrop可以将头像改为圆形。
给历史聊天添加监听
上边已经写过了,用EMMessage监听,在onMessageReceived方法中refresh,添加监听方法。Easeui本身没有添加这个监听,集成好了之后A发信息给B,历史列表不会刷新。
历史聊天头像不展示问题
在B没有登录时,A发信息给B,B登录,历史消息列表会有A,但是因为没有执行onMessageReceived 方法,现在map中是没有A的信息的,头像将展示不出来,解决:找到EaseConversationListFragment类中的 loadConversationList 方法,会话列表刷新时都是执行此方法,我们判断第一次创建fragment时执行存储方法。