最近,經(jīng)常有朋友問到,如何集成環(huán)信頭像,怎么才能快速顯示頭像,因時(shí)間緊急,很多朋友都沒有時(shí)間慢慢的研究代碼,這里大家稍微花10分鐘看一下文章,看完后再花5分鐘改一下代碼,即可達(dá)到你們所要的效果。
當(dāng)然這個(gè)是在你直接復(fù)制了demo中的工具類和必要的UI的前提下實(shí)現(xiàn)的。簡(jiǎn)短說明簡(jiǎn)單暴力的方法:除UI外的其他所有類先復(fù)制到自己工程中,UI部分MainActivity中的代碼需要一個(gè)一個(gè)復(fù)制過去,如與自己項(xiàng)目沖突的需要調(diào)整,然后ChatActivity/ChatFragment也復(fù)制過去,這就可以進(jìn)行聊天了。不過頭像就是大家所遇到的頭像顯示不了,昵稱顯示為環(huán)信號(hào)碼。
環(huán)信官方是有給出頭像的設(shè)置的,不過大部分朋友看了之后都是暈呼呼的。官方給出的提示如下:方法一 從APP服務(wù)器獲取昵稱和頭像
昵稱和頭像的獲?。寒?dāng)收到一條消息(群消息)時(shí),得到發(fā)送者的用戶ID,然后查找手機(jī)本地?cái)?shù)據(jù)庫(kù)是否有此用戶ID的昵稱和頭像,如沒有則調(diào)用APP服務(wù)器接口通過用戶ID查詢出昵稱和頭像,然后保存到本地?cái)?shù)據(jù)庫(kù)和緩存,下次此用戶發(fā)來信息即可直接查詢緩存或者本地?cái)?shù)據(jù)庫(kù),不需要再次向APP服務(wù)器發(fā)起請(qǐng)求
昵稱和頭像的更新:當(dāng)點(diǎn)擊發(fā)送者頭像時(shí)加載用戶詳情時(shí)從APP服務(wù)器查詢此用戶的具體信息然后更新本地?cái)?shù)據(jù)庫(kù)和緩存。當(dāng)用戶自己更新昵稱或頭像時(shí),也可以發(fā)送一條透?jìng)飨⒌狡渌脩艉陀脩羲诘娜海瑏砀略撚脩舻年欠Q和頭像。
方法二 從消息擴(kuò)展中獲取昵稱和頭像
昵稱和頭像的獲?。喊延脩艋镜年欠Q和頭像的URL放到消息的擴(kuò)展中,通過消息傳遞給接收方,當(dāng)收到一條消息時(shí),則能通過消息的擴(kuò)展得到發(fā)送者的昵稱和頭像URL,然后保存到本地?cái)?shù)據(jù)庫(kù)和緩存。當(dāng)顯示昵稱和頭像時(shí),請(qǐng)從本地或者緩存中讀取,不要直接從消息中把賦值拿給界面(否則當(dāng)用戶昵稱改變后,同一個(gè)人會(huì)顯示不同的昵稱)。
昵稱和頭像的更新:當(dāng)擴(kuò)展消息中的昵稱和頭像URI與當(dāng)前本地?cái)?shù)據(jù)庫(kù)和緩存中的相應(yīng)數(shù)據(jù)不同的時(shí)候,需要把新的昵稱保存到本地?cái)?shù)據(jù)庫(kù)和緩存,并下載新的頭像并保存到本地?cái)?shù)據(jù)庫(kù)和緩存。
---------------------------------------------------------------------------------------------
個(gè)人推薦使用方法2,優(yōu)勢(shì)比較明顯,不僅可以設(shè)置頭像、昵稱,甚至以后出現(xiàn)的是否管理員,或者自己APP中的身份標(biāo)志,如:店小二、醫(yī)生、客服等等都可以再定義注明,暴力而簡(jiǎn)單,不需要考慮對(duì)方更新頭像或昵稱,而軟件沒重啟的情況下怎么去更新頭像和昵稱等等復(fù)雜的問題。本指導(dǎo)以最簡(jiǎn)單的集成為指導(dǎo),工具類可使用自己軟件中的,或通過別的方式實(shí)現(xiàn)。
方法2的集成步驟:
1、在登錄的時(shí)候,把自己登錄成功時(shí)后臺(tái)返回的信息保存到sharedpreferences中,需要包含需要的頭像和昵稱。
new Thread(new Runnable() {
@Override
public void run() {
EMClient.getInstance().login(username, password, new EMCallBack() {
@Override
public void onSuccess() {
// 登陸成功,保存用戶昵稱與頭像URL
AppSPUtils.setValueToPrefrences("name", loginBean.getName());
AppSPUtils.setValueToPrefrences("logoUrl", loginBean.getLogoUrl());
// 將自己服務(wù)器返回的環(huán)信賬號(hào)、昵稱和頭像URL設(shè)置到幫助類中。
DemoHelper.getInstance().getUserProfileManager().updateCurrentUserNickName(loginBean.getName());
DemoHelper.getInstance().getUserProfileManager().setCurrentUserAvatar(loginBean.getLogoUrl());
DemoHelper.getInstance().setCurrentUserName(loginUser.getHxId()); // 環(huán)信Id
// ------以下參考demo中的,加載群組和加載消息。然后跳轉(zhuǎn)到首頁(yè)-------
2、AppSPUtils是個(gè)人寫的一個(gè)工具類,大家可以自己寫一個(gè),給出參考代碼。
public class AppSPUtils {
private final static int MODE_SPEC = android.os.Build.VERSION.SDK_INT <= 10 ? 0 : Context.MODE_MULTI_PROCESS;
public static SharedPreferences getSharedPreferences(String name) {
return MainApplication.getContext().getSharedPreferences(name,
Context.MODE_PRIVATE | MODE_SPEC);
}
public static SharedPreferences getAppSharedPreferences() {
return getSharedPreferences(Constants.SP_APP);
}
public static String getValueFromPrefrences(String key, String defaultValue) {
return getValueFromPrefrences(getAppSharedPreferences(), key, defaultValue);
}
public static void setValueToPrefrences(String key, String value) {
try {
SharedPreferences preferences = getAppSharedPreferences();
if (null != preferences) {
preferences.edit().putString(key, value).commit();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 退出登錄時(shí)要調(diào)用
public static void clean() {
try {
SharedPreferences preferences = getAppSharedPreferences();
if (null != getAppSharedPreferences()) {
getAppSharedPreferences().edit().clear().commit();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、保存好自己的信息后,已經(jīng)成功了四分之一,現(xiàn)在是如何將自己的頭像昵稱等信息發(fā)送出去,最簡(jiǎn)單的就是使用擴(kuò)展消息了,在ChatActivity中可以看到,基本上只做了一件事,保證只有一個(gè)ChatActivity,那我們的代碼在哪里?就在ChatFragment里面。找到代碼,可以看到其實(shí)它是繼承自EaseChatFragment,很多內(nèi)容在easeui中已經(jīng)做好了。
這時(shí)你會(huì)發(fā)現(xiàn)ChatFragment類中有一個(gè)擴(kuò)展屬性的說明,沒錯(cuò),就是這個(gè)方法,把你要發(fā)送的內(nèi)容盡情的發(fā)送吧,現(xiàn)附上發(fā)送頭像和昵稱的代碼:
@Override
public void onSetMessageAttributes(EMMessage message) {
if (isRobot) {
// 設(shè)置消息擴(kuò)展屬性
message.setAttribute("em_robot_message", isRobot);
}
// 通過擴(kuò)展屬性,將userPic和userName發(fā)送出去。
String userPic = AppSPUtils.getValueFromPrefrences("logoUrl", "");
if (!TextUtils.isEmpty(userPic)) {
message.setAttribute("userPic", userPic);
}
String userName = AppSPUtils.getValueFromPrefrences("name", "");
if (!TextUtils.isEmpty(userName)) {
message.setAttribute("userName", userName);
}
}
4、發(fā)送完成,你已經(jīng)完成了四分之二的任務(wù)了。發(fā)送完成后,肯定需要一個(gè)接收,其實(shí)demo中的廣播已經(jīng)接收好了,那么我們跟隨著廣播的腳步,來到DemoHelper這個(gè)類,初次看這個(gè)類,都是云一樣的感覺,經(jīng)過一番查找,發(fā)現(xiàn)有個(gè)onMessageReceived的方法,并且還有注釋“全局監(jiān)聽”,趕緊開工,試試接收吧,可以自己打一下log出來看是不是拿到了我們要的。并且照著demoHelper中的保存方法,將接收到的內(nèi)容保存起來。
@Override
public void onMessageReceived(List messages) {
for (EMMessage message : messages) {
message.setMsgTime(System.currentTimeMillis());
//************接收并處理擴(kuò)展消息***********************
String userName = message.getStringAttribute("userName", "");
String userPic = message.getStringAttribute("userPic", "");
String hxIdFrom = message.getFrom();
EaseUser easeUser = new EaseUser(hxIdFrom);
easeUser.setAvatar(userPic);
easeUser.setNick(userName);
// 存入內(nèi)存
getContactList();
contactList.put(hxIdFrom, easeUser);
// 存入db
UserDao dao = new UserDao(MainApplication.getContext());
List users = new ArrayList();
users.add(easeUser);
dao.saveContactList(users);
getModel().setContactSynced(true);
// 通知listeners聯(lián)系人同步完畢
notifyContactsSyncListener(true);
if (isGroupsSyncedWithServer()) {
notifyForRecevingEvents();
}
// ******************擴(kuò)展信息處理完成**********************
EMLog.d(TAG, "onMessageReceived id : " + message.getMsgId());
// 應(yīng)用在后臺(tái),不需要刷新UI,通知欄提示新消息
if (!easeUI.hasForegroundActivies()) {
getNotifier().onNewMsg(message);
}
}
}
5、信息都收到了,就差最后一步就可以顯示了,不知道你們是不是激動(dòng),反正我是激動(dòng)了。那在哪里進(jìn)行顯示呢?還是在DemoHelper中,找到getUserInfo方法,代碼如下:
private EaseUser getUserInfo(String hxId) {
// 獲取user信息,demo是從內(nèi)存的好友列表里獲取,
// 實(shí)際開發(fā)中,可能還需要從服務(wù)器獲取用戶信息,
// 從服務(wù)器獲取的數(shù)據(jù),最好緩存起來,避免頻繁的網(wǎng)絡(luò)請(qǐng)求
if (hxId.equals(EMClient.getInstance().getCurrentUser())) {
EaseUser currentUserInfo = getUserProfileManager().getCurrentUserInfo();
return currentUserInfo;
}
EaseUser easeUser;
if (contactList != null && contactList.containsKey(hxId)) {
} else { // 如果內(nèi)存中沒有,則將本地?cái)?shù)據(jù)庫(kù)中的取出到內(nèi)存中。
getContactList();
}
// // TODO 獲取不在好友列表里的群成員具體信息,即陌生人信息,demo未實(shí)現(xiàn)
// if (user == null && getRobotList() != null) {
// user = getRobotList().get(hxId);
// }
easeUser = contactList.get(hxId);
if(easeUser == null){
easeUser = new EaseUser(hxId);
} else {
if(TextUtils.isEmpty(easeUser.getNick())){ // 如果名字為空,則顯示環(huán)信號(hào)碼
easeUser.setNick(easeUser.getUsername());
}
}
return easeUser;
}
OK,大功告成,到這里你的頭像已經(jīng)可以顯示了。。恭喜你!
有朋友還有疑問,為什么頭像是方形的,要變成圓形怎么辦?指?jìng)€(gè)路,在easeui中的utils包下,找到EaseUserUtils,這里就是顯示用戶頭像和用戶昵稱的地方,通過Glide可以輕松顯示圓形頭像,百度有很多方法,這里就不多講了,同樣,你也可以通過其他圖形加載框架來完成。
很多朋友不明白擴(kuò)展消息的是什么東西,也不明白為什么照著代碼敲就能夠完成頭像的顯示,那下面就給大家粗淺的講講所涉及到的邏輯關(guān)系。
擴(kuò)展消息:就是你每一次發(fā)送消息,都會(huì)附帶在你發(fā)送內(nèi)容上面的額外消息,他會(huì)隨著你的內(nèi)容發(fā)送出去,每次會(huì)多一點(diǎn)點(diǎn)流量,但微乎其微,個(gè)人認(rèn)為并無多大影響。
顯示頭像邏輯:區(qū)分為本地化緩存和運(yùn)行內(nèi)存緩存,在demoHelper中可以發(fā)現(xiàn),有一個(gè)成員變量private Map contactList; 這個(gè)就是用來保存在運(yùn)行內(nèi)存緩存的,只有通過運(yùn)行緩存,顯示頭像是最順暢的,如果每次都從數(shù)據(jù)庫(kù)中讀取的話,聊天界面會(huì)比較卡,有朋友保存在SP里面,以ID做為KEY,頭像和昵稱等拼接做為value進(jìn)行緩存,取出后再拆分開分別取值,據(jù)說是不卡,大家可以試一下。
本地化存儲(chǔ)是為了在每次打開軟件的時(shí)候,從本地存儲(chǔ)中拿到運(yùn)行內(nèi)存中使用做準(zhǔn)備,大家可以認(rèn)真看看demoHelper和MainActivity中的代碼。
----------------------------------------------------------------------------------
講了方法2設(shè)置頭像,那么方法1,個(gè)人不推薦,但這里給出處理的過程,如有個(gè)別有需求的,可以按方法1來處理:
1、登錄成功后,在手機(jī)子線程,訪問你們的后臺(tái)服務(wù)器,拿到所有好友的環(huán)信ID,頭像,昵稱。然后按上面的保存方法,保存到本地中,完成后發(fā)送廣播或EventBus之類到,刷新消息界面和ChatFragment。
2、在getUserInfo中,寫和上面擴(kuò)展消息一樣的內(nèi)容,將如果運(yùn)行緩存和本地都拿不到,則發(fā)起網(wǎng)絡(luò)請(qǐng)求到后臺(tái)獲取頭像,等請(qǐng)求到內(nèi)容后,再發(fā)出廣播或EventBus通知刷新消息界面和ChatFragment。
-------------------------------------------------------------------------------------
以上僅為本人在開發(fā)過程中的一點(diǎn)小小心得,demo中的保存運(yùn)存和本地儲(chǔ)存的方法,大家也可以單獨(dú)寫,并不會(huì)影響程序的運(yùn)行,當(dāng)然也有兄弟寫過發(fā)表,大概根據(jù)實(shí)際情況擇優(yōu)選取即可。小弟學(xué)識(shí)淺薄,如果有錯(cuò)漏的,歡迎大家糾正。
文章同步發(fā)表在imgeek社區(qū),原文地址http://www.imgeek.org/article/825307875
如有需要,可以到494167135群中與大家交流學(xué)習(xí)。本人:樂奇奇,QQ:730326762。大家優(yōu)先加群,謝謝。