Android 環信(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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM