環信(Android)設定頭像和暱稱的方法 一
最近,經常有朋友問到,如何整合環信頭像,怎麼才能快速顯示頭像,因時間緊急,很多朋友都沒有時間慢慢的研究程式碼,這裡大家稍微花10分鐘看一下文章,看完後再花5分鐘改一下程式碼,即可達到你們所要的效果。
當然這個是在你直接複製了demo中的工具類和必要的UI的前提下實現的。簡短說明簡單暴力的方法:除UI外的其他所有類先複製到自己工程中,UI部分MainActivity中的程式碼需要一個一個複製過去,如與自己專案衝突的需要調整,然後ChatActivity/ChatFragment也複製過去,這就可以進行聊天了。不過頭像就是大家所遇到的頭像顯示不了,暱稱顯示為環訊號碼。
環信官方是有給出頭像的設定的,不過大部分朋友看了之後都是暈呼呼的。官方給出的提示如下:
方法一 從APP伺服器獲取暱稱和頭像
暱稱和頭像的獲取:當收到一條訊息(群訊息)時,得到傳送者的使用者ID,然後查詢手機本地資料庫是否有此使用者ID的暱稱和頭像,如沒有則呼叫APP伺服器介面通過使用者ID查詢出暱稱和頭像,然後儲存到本地資料庫和快取,下次此使用者發來資訊即可直接查詢快取或者本地資料庫,不需要再次向APP伺服器發起請求
暱稱和頭像的更新:當點擊發送者頭像時載入使用者詳情時從APP伺服器查詢此使用者的具體資訊然後更新本地資料庫和快取。當用戶自己更新暱稱或頭像時,也可以傳送一條透傳訊息到其他使用者和使用者所在的群,來更新該使用者的暱稱和頭像。
方法二 從訊息擴充套件中獲取暱稱和頭像
暱稱和頭像的獲取:把使用者基本的暱稱和頭像的URL放到訊息的擴充套件中,通過訊息傳遞給接收方,當收到一條訊息時,則能通過訊息的擴充套件得到傳送者的暱稱和頭像URL,然後儲存到本地資料庫和快取。當顯示暱稱和頭像時,請從本地或者快取中讀取,不要直接從訊息中把賦值拿給介面(否則當用戶暱稱改變後,同一個人會顯示不同的暱稱)。
暱稱和頭像的更新:當擴充套件訊息中的暱稱和頭像URI與當前本地資料庫和快取中的相應資料不同的時候,需要把新的暱稱儲存到本地資料庫和快取,並下載新的頭像並儲存到本地資料庫和快取。
個人推薦使用方法2,優勢比較明顯,不僅可以設定頭像、暱稱,甚至以後出現的是否管理員,或者自己APP中的身份標誌,如:店小二、醫生、客服等等都可以再定義註明,暴力而簡單,不需要考慮對方更新頭像或暱稱,而軟體沒重啟的情況下怎麼去更新頭像和暱稱等等複雜的問題。本指導以最簡單的整合為指導,工具類可使用自己軟體中的,或通過別的方式實現。
方法2的整合步驟:
1、在登入的時候,把自己登入成功時後臺返回的資訊儲存到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());
// 將自己伺服器返回的環信賬號、暱稱和頭像URL設定到幫助類中。
DemoHelper.getInstance().getUserProfileManager().updateCurrentUserNickName(loginBean.getName());
DemoHelper.getInstance().getUserProfileManager().setCurrentUserAvatar(loginBean.getLogoUrl());
DemoHelper.getInstance().setCurrentUserName(loginUser.getHxId()); // 環信Id
// ------以下參考demo中的,載入群組和載入訊息。然後跳轉到首頁-------
2、AppSPUtils是個人寫的一個工具類,大家可以自己寫一個,給出參考程式碼。
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();
}
}
// 退出登入時要呼叫
public static void clean() {
try {
SharedPreferences preferences = getAppSharedPreferences();
if (null != getAppSharedPreferences()) {
getAppSharedPreferences().edit().clear().commit();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、儲存好自己的資訊後,已經成功了四分之一,現在是如何將自己的頭像暱稱等資訊傳送出去,最簡單的就是使用擴充套件訊息了,在ChatActivity中可以看到,基本上只做了一件事,保證只有一個ChatActivity,那我們的程式碼在哪裡?就在ChatFragment裡面。找到程式碼,可以看到其實它是繼承自EaseChatFragment,很多內容在easeui中已經做好了。
這時你會發現ChatFragment類中有一個擴充套件屬性的說明,沒錯,就是這個方法,把你要傳送的內容盡情的傳送吧,現附上傳送頭像和暱稱的程式碼:
@Override
public void onSetMessageAttributes(EMMessage message) {
if (isRobot) {
// 設定訊息擴充套件屬性
message.setAttribute("em_robot_message", isRobot);
}
// 通過擴充套件屬性,將userPic和userName傳送出去。
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、傳送完成,你已經完成了四分之二的任務了。傳送完成後,肯定需要一個接收,其實demo中的廣播已經接收好了,那麼我們跟隨著廣播的腳步,來到DemoHelper這個類,初次看這個類,都是雲一樣的感覺,經過一番查詢,發現有個onMessageReceived的方法,並且還有註釋“全域性監聽”,趕緊開工,試試接收吧,可以自己打一下log出來看是不是拿到了我們要的。並且照著demoHelper中的儲存方法,將接收到的內容儲存起來。
@Override
public void onMessageReceived(List<EMMessage> messages) {
for (EMMessage message : messages) {
message.setMsgTime(System.currentTimeMillis());
//************接收並處理擴充套件訊息***********************
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);
// 存入記憶體
getContactList();
contactList.put(hxIdFrom, easeUser);
// 存入db
UserDao dao = new UserDao(MainApplication.getContext());
List<EaseUser> users = new ArrayList<EaseUser>();
users.add(easeUser);
dao.saveContactList(users);
getModel().setContactSynced(true);
// 通知listeners聯絡人同步完畢
notifyContactsSyncListener(true);
if (isGroupsSyncedWithServer()) {
notifyForRecevingEvents();
}
// ******************擴充套件資訊處理完成**********************
EMLog.d(TAG, "onMessageReceived id : " + message.getMsgId());
// 應用在後臺,不需要重新整理UI,通知欄提示新訊息
if (!easeUI.hasForegroundActivies()) {
getNotifier().onNewMsg(message);
}
}
}
5、資訊都收到了,就差最後一步就可以顯示了,不知道你們是不是激動,反正我是激動了。那在哪裡進行顯示呢?還是在DemoHelper中,找到getUserInfo方法,程式碼如下:
private EaseUser getUserInfo(String hxId) {
// 獲取user資訊,demo是從記憶體的好友列表裡獲取,
// 實際開發中,可能還需要從伺服器獲取使用者資訊,
// 從伺服器獲取的資料,最好快取起來,避免頻繁的網路請求
if (hxId.equals(EMClient.getInstance().getCurrentUser())) {
EaseUser currentUserInfo = getUserProfileManager().getCurrentUserInfo();
return currentUserInfo;
}
EaseUser easeUser;
if (contactList != null && contactList.containsKey(hxId)) {
} else { // 如果記憶體中沒有,則將本地資料庫中的取出到記憶體中。
getContactList();
}
// // TODO 獲取不在好友列表裡的群成員具體資訊,即陌生人資訊,demo未實現
// 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())){ // 如果名字為空,則顯示環訊號碼
easeUser.setNick(easeUser.getUsername());
}
}
return easeUser;
}
OK,大功告成,到這裡你的頭像已經可以顯示了。。恭喜你!
有朋友還有疑問,為什麼頭像是方形的,要變成圓形怎麼辦?指個路,在easeui中的utils包下,找到EaseUserUtils,這裡就是顯示使用者頭像和使用者暱稱的地方,通過Glide可以輕鬆顯示圓形頭像,百度有很多方法,這裡就不多講了,同樣,你也可以通過其他圖形載入框架來完成。
很多朋友不明白擴充套件訊息的是什麼東西,也不明白為什麼照著程式碼敲就能夠完成頭像的顯示,那下面就給大家粗淺的講講所涉及到的邏輯關係。
擴充套件訊息:就是你每一次傳送訊息,都會附帶在你傳送內容上面的額外訊息,他會隨著你的內容傳送出去,每次會多一點點流量,但微乎其微,個人認為並無多大影響。
顯示頭像邏輯:區分為本地化快取和執行記憶體快取,在demoHelper中可以發現,有一個成員變數private Map<String, EaseUser> contactList;
這個就是用來儲存在執行記憶體快取的,只有通過執行快取,顯示頭像是最順暢的,如果每次都從資料庫中讀取的話,聊天介面會比較卡,有朋友儲存在SP裡面,以ID做為KEY,頭像和暱稱等拼接做為value進行快取,取出後再拆分開分別取值,據說是不卡,大家可以試一下。
本地化儲存是為了在每次開啟軟體的時候,從本地儲存中拿到執行記憶體中使用做準備,大家可以認真看看demoHelper和MainActivity中的程式碼。
講了方法2設定頭像,那麼方法1,個人不推薦,但這裡給出處理的過程,如有個別有需求的,可以按方法1來處理:
1、登入成功後,在手機子執行緒,訪問你們的後臺伺服器,拿到所有好友的環信ID,頭像,暱稱。然後按上面的儲存方法,儲存到本地中,完成後傳送廣播或EventBus之類到,重新整理訊息介面和ChatFragment。
2、在getUserInfo中,寫和上面擴充套件訊息一樣的內容,將如果執行快取和本地都拿不到,則發起網路請求到後臺獲取頭像,等請求到內容後,再發出廣播或EventBus通知重新整理訊息介面和ChatFragment。
demo中的儲存運存和本地儲存的方法,大家也可以單獨寫
安卓交流群 : 595856941