前言
最近項目需要及時通訊功能,和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時執行存儲方法。