環信easeui集成:坑總結2018


 

環信EaseUI 集成,集成不做描述,看文檔即可,下面主要談一些對easeui的個性化需求修改。

 

該篇文章將解決的問題:

1、如何將App用戶體系的用戶名和用戶頭像 顯示於環信的easeui

2、如何從library中調用app中的方法?

3、easeui頭像都是方形的,如果修改為圓型顯示?

4、環信用戶注冊問題:環信用戶注冊需要交給服務器注冊用戶的同時去注冊

5、環信登錄和注銷sdk的使用在App 客戶端實現,同步於App用戶的登錄和退出

6、第一次會話發起的時候,此時發消息的和收消息的用戶的數據可能不在數據庫中存在,需要在這個情景之下單獨先進行雙方的數據存儲   

7、創建群聊方法失敗

8、群聊功能,能接受到消息,但是發送消息發不出去

9、會話界面只有點擊事件,沒有長按點擊事件(沒有刪除操作,需要自行添加長按彈對話框刪除操作)

10、easeui 7.0+ 8.0+ 調用會話拍照功能,崩潰

11、easeui 點擊對方的視頻消息,崩潰問題

-------------------------------------------------------------------------------------------------------------------- 

 

一、如何將App用戶體系的用戶名和用戶頭像 顯示於環信的easeui

  這個問題是所有人都想解決的,集成easeui之后 ,雖然大部分功能給我們做好了,但是他是顯示的環信用戶體系的用戶名和默認的頭像。

  這個用戶名是唯一的,官方提供了兩種方式來解決。這里我們使用用戶發送消息攜帶擴展信息的方式來實現。

  首先看一下環信的用戶體系,用戶名(唯一值,easeui中顯示的用戶名就是他,實際上,我們自己數據庫的用戶體系中,就把用戶的唯一id作為環信的用戶名)

  環信的用戶名 == 后台數據庫的id  , 目的保證唯一值,區分用戶信息

  App端 需要一個數據庫,每一個記錄有三個字段: id ,userName, userAvatar

 

  

  

  實現思路:

  1、發送消息的時候(一般是當前登錄用戶,取名用戶A) ,將項目后台用戶A的id、頭像url和用戶名字符串作為消息的擴展屬性一並發送出去

        找到EaseChatFragment文件

      

    大致看一下,該行數范圍內的代碼,很明顯是一個個發送各種類型消息的方法,方法內最后都調用了sendMessage()方法,

    顯然我們需要在sendMessage()方法內 給 消息(message) 添加擴展屬性即可 ,如下圖

    

              添加了932-935行代碼,實現了當app當前登錄用戶每次發消息(不管什么類型的消息)都會添加3個擴展屬性,分別為發出人的用戶名,用戶頭像,用戶id

    (注意,這個id要在自己的服務器數據里是唯一的,一個用戶一個id,用時要求后端開發人員在環信用該id在環信用戶體系里作為唯一的用戶名,保證自己服務器里一個用戶對於環信用戶體系里的一個用戶)  

    

    總結:

    第一步,給每個發出去的消息添加3個擴展屬性

    

    2、發送方處理好了,只需要給每個發出去的消息添加3個擴展屬性即可,接下來就是收消息方的處理

       這里每個用戶大致有3個主要界面,會話歷史界面,聯系人界面,單聊窗口界面。

       其中會話歷史列表界面和聯系人界面類似,下面只以會話歷史列表界面為例,實現用戶頭像和用戶名的顯示  

       會話歷史界面對應的是EaseConversationListFragment界面。

       閱讀下代碼,里面有一個refresh()方法,很現實就是更新列表的方法。

       注意的是,該fragment里面是沒有監聽消息更新的listener,則第一步先根據文檔在該fragment里面添加一個消息監聽

      

       同時,注冊和注銷監聽

       

         

      仔細看一個EMMessageListener 里面有一個onMessageReceived(List<Message> message){}回調

      很顯然,當有消息收到的時候,會執行該方法回調,同時把消息數據返回,注意這里的消息是一個集合的消息數據

         結合第一步發出去的每一個消息都帶有發送人的用戶名,用戶頭像,用戶唯一id 三個信息,則這里只需要把三個信息從每一個消息message里面提取出來即可  

      

     代碼很簡單,注意這里需要用到數據庫的知識,我這里使用的是 greendao , 關於數據庫的學習這里就不說了,不會的童鞋可以自行去學習

       總結:

     第二步 就是一個獲取每一個消息中的擴展屬性,知道這個每一條消息是哪個用戶發來的,他的用戶名用戶頭像用戶唯一id都可以獲取到,然后存儲到數據庫中

 

      3、上面兩步很明顯了, 一個是告訴對方 我叫什么、我的頭像信息、我的唯一id,一個是接收方,得到每一個消息的擴展屬性進行數據庫存儲。

       該流程下第三步就很明顯了,就是把存儲的數據庫信息中獲取消息所屬用戶id的頭像和名字 顯示在界面上即可(id作為唯一標准)。

      ①、以會話歷史列表界面(EaseConversationListFragment)為例,聯系人界面類似

      找到那行關鍵代碼:refresh()

      

      handler發送了一個消息,繼續找對該消息的處理

      

      很顯然,當有消息來的時候,先清空消息列表,然后加載當前消息,刷新listview

      看一下conversationListView.refresh()做了什么? ctrl+鼠標左鍵點擊該方法代碼進入了 EaseConversationList.java

      

      依舊是handler發送一個消息,繼續查詢對該消息的處理

      

      最后定位到了adapter.notifyDataSetChanged(),刷新列表 ,定位到EaseConversationAdapter

      總結一下,當有新消息來的時候,刷新適配器。

      到這里很顯然知道該怎么做了,刷新適配器的時候,更改ui即可了

            

       兩個if一個else,只需要改else里面部分即可,為啥? 看注釋

      ①、從數據庫中根據id獲取用戶的頭像和昵稱

        如果數據庫中沒有 ,則用默認的昵稱和頭像

        如果數據庫中油 ,則顯示,注意,

        可以看出原來easeui顯示的用戶名是環信系統里面的用戶名,實際上我們把它作為數據庫的id,用該id對應的用戶名來顯示

        顯示用戶名改為:

      ②、用戶名很簡單,把原本顯示id的改為顯示id對應的用戶名字符串的即可

        頭像呢,定位到EaseUserUtils.setUserAvatar()方法,如下,是easeui原來的使用方式,可以看到都用了一個默認的圖片來顯示頭像

        

        則我們只需要對應在EaseUserUtils里面寫一個定制的顯示頭像的方法 , 將第二個參數 把從數據庫對應id取出的記錄中的頭像url替換,顯示

        

        注意,這里Glide的使用,添加了一個.dontAnimate()的使用,用於解決特定情況下第一個不會正常顯示圖片的情況,算是一個小bug,可根據自身情況添加。

 

         總結:想要在會話歷史列表顯示實際的頭像和用戶名 只需要在list對應的adapter修改顯示ui的部分代碼即可。

      

      4、還剩一個關鍵的界面,將頭像和用戶名顯示出來,就是會話界面 EaseChatFragment

        這個界面需要修改的部分:

        ①標題,修改為聊天對象的用戶名,默認是環信用戶體系中聊天用戶的用戶名,即數據庫存的三個擴展屬性的id

        ②發送的消息,即app當前用戶發出去的item的頭像和用戶名,右側部分

        ③接受的消息,即app其他用戶發過來的item的頭像和用戶名,左側部分

        下面按順序解決,

       先定位到聊天界面的layout : ease_fragment_chat.xml

       

          

       如上圖,就幾個view

       很顯然,EaseTitleBar 就是聊天界面上的標題

        其他,EaseChatMessageList是聊天item的列表

       主要修改這兩處view的使用

       ctrl+鼠標左鍵定位到EaseTitleBar這個自定義控件位置

       

       在ctrl+鼠標左鍵點擊EaseTitleBar看一下這個控件哪里有用到

       

       跟聊天有關,那很顯然就是EaseBaseFragment了,查看一下該文件代碼,這個fragment是一個抽象類,有兩個方法initview setUpView ,而EaseChatFragment繼承了該類

          

 

        則再回到easeChatFragment里面 查詢一下setUpView 和 initView的使用

        

 

           到這里就很顯然了, 這便是單聊情況下的if

         easeui原代碼是灰色注釋掉的部分,可以看到titleBar顯示的是用戶的用戶名,即環信用戶體系中的用戶名,而我們把他作為id,唯一值

        所以在這里還是根據這個id來去數據庫中找尋id對應的用戶名 setTitle()進去即可,修改聊天界面標題為對方用戶名就是這么簡單。

 

        接下來是修改聊天界面的發送方和接收方的頭像問題。

          這個具體找到代碼的思路就不介紹了,比較麻煩,直接定位到想要代碼吧

        

        這里就是各種類型的消息的item的自定義控件,都繼承自EaseChatRow類

        然后研究一下EaseChatRow類 ,發現了關鍵代碼

        

        比較容易看懂,當消息是發出去的時候,調用了一個現實頭像的方法,當消息是接收的時候,定義了一個現實頭像和用戶名的方法

        那解決方法,就是從該處在數據庫中根據id獲取到頭像和用戶名的數據顯示即可。

           思路如此,不在細講

         

 

 

 

、如何從library中調用app中的方法?

   當依賴easeui的時候,是用import module的形式導入的,所以主程序是可以調用easeui類庫中的類和方法,但是反之不行

    當數據庫操作的時候,發現該問題,解決辦法就是反射調用,具體查詢相關文章

   

 

三、easeui頭像都是方形的,如果修改為圓型顯示?

   找一個用到顯示頭像的xml代碼

   

    可以看到easeui使用了一個自定義控件來顯示EaseImageView

    查看該控件源碼:

   

   發現

   

     說明該控件的shapeType屬性是來控制圖片是方形顯示還是圓形顯示的。

   查詢源碼發現init()方法對該屬性進行了初始話,默認值為0 ,如果想圓形顯示,則改為1即可

    

         如此一來,不該顯示圖片的控件,不該每一個調用控件的自定義屬性 即可實現統一圓形顯示。

 

 

 

其他注意點:

1、環信用戶注冊需要交給服務器注冊用戶的同時去注冊

2、環信登錄和注銷sdk的使用在App 客戶端實現,同步於App用戶的登錄和退出

3、第一次會話發起的時候,此時發消息的和收消息的用戶的數據可能不在數據庫中存在,需要在這個情景之下單獨先進行雙方的數據存儲   

4、上面講到一個接收到新消息的回調方法  onMessageReceived  

  會有一種情況。B用戶尚未登錄APP, A用戶給B用戶發了消息(兩個用戶之間是第一次會話,並且是A給B發起的會話,也就是說B用戶那邊是沒有數據庫存儲A用戶的三個信息的),B用戶登錄消息之后 會有消息列表,但是因為沒有執行

  onMessageReceived 方法,導致沒有對A用戶的消息中的擴展數據進行數據庫存儲,所以會導致B用戶這邊會話列表中A用戶的頭像和用戶名顯示不出,解決辦法 定位到EaseConversationListFragment類中的 loadConversationList 方法

  查看源碼得知會話列表刷新的時候都會執行,那就在這個方法中對所有的消息的擴展字段進行數據庫存儲,且只有第一次創建該fragment的時候才執行存儲

   

    onCreate()中

   boolean isLoadData = false; // 是否已經緩存了數據  用於界面剛登陸的時候 對之前接受到的數據的處理

--------------------------------------------------------------------------------------------------------------------------------------------------------

5.、創建群聊方法失敗

  

 

  

   報303 錯誤,

  解決辦法,這個方法的使用需要在子線程中進行,不可以在主線程進行

  所以放到Thread里面即可

 

 

6、群聊功能,能接受到消息,但是發送消息發不出去

  經檢查:

  當點擊會話列表 群組item進入會話界面的時候,EaseChatFragment.java 中 的setUpView方法執行了 if(chatType == EaseConstant.CHATTYPE_SINGLE)

  為什么點擊群組item進入的類型是單聊的type, 往上查詢chatType怎么來的

     

     顯然是從Activity中獲取到的,同時還從Activity中獲取到了 toChatUsername 的值

          繼續往上查詢 EaseChatActivity

     

   發現這里進行了setArguments方法,顯然這里不是數據最開始獲取的地方,繼續查,就是進入到EaseChatActivity的intent跳轉調用了

   

   發現了intent傳遞了 但是沒有傳遞

   而顯然一直類型為默認類型EaseConstant.CHATTYPE_SINGLE

     導致群聊進入會話界面的類型是單聊

     所以intent進入EaseChatActivity的時候,將 一並傳遞

     如下:

     

    Log日志:

    

   發現type是GroupChat也就是字符串類型,但是接受的時候是int類型 

           

   找到EMConversation.class類

   

   還有EaseConstant.class類

   

   解決辦法,intent打開EaseChatActivity.class 的時候 傳遞相應的int值即可

    

 7、會話列表item長按事件

  easeui默認是沒有會話列表item長按事件的,體驗上就是會話列表沒有刪除操作

  所以需要我們自行給會話列表添加一個item長按事件監聽

  解決辦法:

  找到EaseConversationListFragment.java  

  這個fragment是會話界面

  找到setUpView()方法,第三行

  

  很明顯這里是單點事件的接口回調

  當然,如果長按事件需要在該fragment處理的,則直接添加長按點擊事件

  

  如果想和單點事件一樣,則需要仿照單點做一個接口回調,這里不再敘述。

 

8、easeui 7.0+ 8.0+ 調用會話拍照功能,崩潰

   easeui調用相機代碼本身沒有適配7.0+ 8.0+ 機型 , 需要自己適配一下

   解決方案:Android項目實戰(四十九):Andoird 7.0+相機適配

   具體調整代碼:

   找到EaseChatFragment文件,這個是會話界面相關

   找到 selectPicFromCamera方法,調用相機方法

      更改代碼如下:

    /**
     * capture new image
     */
    protected void selectPicFromCamera() {
        if (!EaseCommonUtils.isSdcardExist()) {
            Toast.makeText(getActivity(), R.string.sd_card_does_not_exist, Toast.LENGTH_SHORT).show();
            return;
        }

        cameraFile = new File(PathUtil.getInstance().getImagePath(), EMClient.getInstance().getCurrentUser()
                + System.currentTimeMillis() + ".jpg");
        //noinspection ResultOfMethodCallIgnored
        cameraFile.getParentFile().mkdirs();
     // 7.0+ 8.0+ 調用相機適配
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
            intent.putExtra(MediaStore.EXTRA_OUTPUT,
                    FileProvider.getUriForFile(getActivity(),"你的包名.fileprovider", cameraFile));
        }else {
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile));
        }
        startActivityForResult(intent, REQUEST_CODE_CAMERA);
    }

 

 

9、easeui 點擊對方的視頻消息,崩潰問題

   這個問題看日志就知道怎么解決,因為沒有在清單文件中注冊

     解決方法:

  AndroidManifest.xml 文件注冊 EaseShowVideoActivity

   

<activity android:name="com.hyphenate.easeui.ui.EaseShowVideoActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:screenOrientation="portrait"></activity>

 

 andoird7.0+ 機型的適配

 查找EaseCompat.java 文件

 會有如下代碼適配7.0+ 視頻播放的

 

 

 這里要注意 easeui自帶寫的是fileProvider 和 自己寫的AndroidManifest.xml 中的7.0+適配代碼的 authorities 值是否一致,

 按文章上面描述的方法寫的是fileprovider , P小寫,注意 要改成一致,即

 

 否則報錯:

 

 

 

-------------------------------------------------------------------------------------------------------------------------------------------------    

 

有問題歡迎加Android群探討。。

 


免責聲明!

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



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