android即時通訊准脂,基于環(huán)信3.3.4版本,基礎(chǔ)功能開發(fā)詳解檬洞,一步一步帶你實現(xiàn)狸膏。

近期,由于公司新開項目添怔,涉及即時通訊湾戳,幾經(jīng)對比,選擇了環(huán)信平臺广料。話不多說砾脑,進入正題。

大綱:

1.環(huán)信SDK集成艾杏,http://docs.easemob.com/im/200androidclientintegration/10androidsdkimport韧衣,打開鏈接,完成最基礎(chǔ)的sdk集成购桑,并且初始化SDK汹族,這一步我就略過了。

2.聊天準(zhǔn)備其兴,注冊顶瞒,登錄,退出登錄元旬,設(shè)置環(huán)信服務(wù)連接監(jiān)聽榴徐,設(shè)置消息接收監(jiān)聽

3.添加好友

4.好友消息列表處理(根據(jù)最后聊天發(fā)送時間排序)

5.聊天界面消息發(fā)送守问,接收處理

以下是項目中使用環(huán)信sdk完成的功能清單:

聊天界面(1對1好友聊天):

發(fā)送消息類別:文字,語音坑资,圖片耗帕,位置。

好友列表:聊天好友會話列表袱贮。

好友消息列表效果圖

2.聊天準(zhǔn)備仿便,注冊,登錄攒巍,退出登錄嗽仪,設(shè)置環(huán)信服務(wù)連接監(jiān)聽,設(shè)置消息接收監(jiān)聽

2.1-注冊

注冊環(huán)信聊天賬號柒莉,密碼闻坚,用于app客戶端基于環(huán)信服務(wù)器聊天。這一塊兢孝,本項目是由后臺接口注冊窿凤,登錄后返回,也就是說環(huán)信聊天賬號的注冊交由后臺創(chuàng)建跨蟹,客戶端只需在登錄成功后返回接收即可雳殊。當(dāng)然可以根據(jù)自身需求,也可自己創(chuàng)建窗轩。

環(huán)信sdk文檔是這樣描述的:

注冊模式分兩種相种,開放注冊和授權(quán)注冊。只有開放注冊時品姓,才可以客戶端注冊。

開放注冊是為了測試使用箫措,正式環(huán)境中不推薦使用該方式注冊環(huán)信賬號腹备;

授權(quán)注冊的流程應(yīng)該是您服務(wù)器通過環(huán)信提供的 RESTAPI注冊,之后保存到您的服務(wù)器或返回給客戶端斤蔓。

注冊用戶名會自動轉(zhuǎn)為小寫字母植酥,所以建議用戶名均以小寫注冊。(強烈建議開發(fā)者通過后臺調(diào)用 REST 接口去注冊環(huán)信 ID弦牡,客戶端注冊方法不提倡使用友驮。)

//注冊失敗會拋出HyphenateException

EMClient.getInstance().createAccount(username, pwd);//同步方法 (不推薦客戶端注冊)

2.2-登錄

app登錄成功之后,獲取后臺創(chuàng)建好的username驾锰,password卸留。值得注意的是,回調(diào)的三個方法都是位于子線程椭豫,不能夠在方法體內(nèi)做ui操作耻瑟。

調(diào)用環(huán)信api旨指,EMClient.getInstance().login(userName,password,new EMCallBack());進行環(huán)信賬號登錄。

調(diào)用環(huán)信登錄

EMClient.getInstance().groupManager().loadAllGroups();

EMClient.getInstance().chatManager().loadAllConversations();

以上兩個方法是為了保證進入主頁面后本地會話和群組都 load 完畢喳整,根據(jù)自身業(yè)務(wù)調(diào)用谆构,除登錄api成功回調(diào)使用,建議每次啟動app都在啟動頁調(diào)用一次框都。

退出登錄搬素,直接調(diào)用 EMClient.getInstance().logout(true)即可;

環(huán)信登錄成功后,默認為自動登錄魏保,可按需求取消自動登錄options.setAutoLogin(false)熬尺。

EMClient.getInstance().isLoggedInBefore(),判斷環(huán)信賬號登錄狀態(tài)

2.3-(成功登錄環(huán)信后)設(shè)置環(huán)信服務(wù)連接監(jiān)聽

注冊連接監(jiān)聽囱淋,可用作監(jiān)聽設(shè)備登錄唯一猪杭,發(fā)生多點登錄,作出提示妥衣。只需在注冊一次即可皂吮,建議在應(yīng)用首頁注冊,這樣首頁不銷毀就可以做到全局監(jiān)聽的效果税手,進入app注冊監(jiān)聽蜂筹。

退出app時,調(diào)用EMClient.getInstance().removeConnectionListener(MyConnectionListener);銷毀監(jiān)聽芦倒。MyConnectionListener類實現(xiàn)了EMConnectionListener接口

2.3-(成功登錄環(huán)信后)設(shè)置環(huán)信消息接收監(jiān)聽

EMClient.getInstance().chatManager().addMessageListener(msgListener);只需在注冊一次即可艺挪,建議在應(yīng)用首頁注冊,這樣首頁不銷毀就可以做到全局監(jiān)聽的效果兵扬,進入app注冊監(jiān)聽麻裳,退出app調(diào)用EMClient.getInstance().chatManager().removeMessageListener(msgListener);

值得注意的是,EMMessageListener的眾多回調(diào)方法中器钟, onMessageReceived(List messages)是最重要的方法津坑,所有消息接收都在此方法中,但是看方法的參數(shù)傲霸,竟然是list集合疆瑰,這里面我們只需要獲取list里面的第一個數(shù)據(jù)即可,List<EMMessage> message = messages.get(0);昙啄,這條是最新的消息穆役。EMMessageListener的回調(diào)方法依然是在子線程中,所以需要配合handler進行ui操作梳凛。

消息接收處理
handler 消息接收

首先是注冊監(jiān)聽耿币,我是在MainActivity首頁設(shè)置的,UserBiz.isLogin() && EMClient.getInstance().isLoggedInBefore()雙重判斷用戶是否已登錄韧拒,環(huán)信賬號登錄掰读。EMReceiveBiz是我自己寫一個處理消息接收的業(yè)務(wù)類秘狞,全局只在MainActivity注冊一次監(jiān)聽,避免收到多次消息蹈集。

關(guān)于MyConnectionListener烁试,上面已經(jīng)有介紹。與消息監(jiān)聽同理拢肆。

設(shè)置消息監(jiān)聽减响,連接監(jiān)聽

然后是銷毀監(jiān)聽,當(dāng)退出app時郭怪,把注冊的2個監(jiān)聽銷毀

EMClient.getInstance().removeConnectionListener(eMConnectionListener);

EMClient.getInstance().chatManager().removeMessageListener(emReceiveBiz.msgListener);

EMReceiveBiz里面用到了handler支示,所以為了防止內(nèi)存泄露,把handler監(jiān)聽銷毀鄙才。

銷毀監(jiān)聽

3.添加好友

EMClient.getInstance().contactManager().setContactListener(newEMContactListener()); 注冊好友監(jiān)聽

//參數(shù)為要添加的好友的username和添加理由

EMClient.getInstance().contactManager().addContact(toAddUsername, reason);

一般添加好友除了環(huán)信平臺添加好友颂鸿,本地接口也需要添加到好友列表,所以reason根據(jù)需求設(shè)置參數(shù)攒庵,比如本地接口添加好友需要用戶userId嘴纺,那么可以將reason設(shè)置為自己的userId,發(fā)送成功后浓冒,對方將在onContactInvited方法中獲取到你的環(huán)信賬號栽渴,與你的userId,這樣再處理接收好友請求稳懒,調(diào)用本地接口添加好友闲擦。

添加好友監(jiān)聽

4.好友消息列表處理(根據(jù)最后聊天發(fā)送時間排序)

我們看到QQ,微信也好场梆,消息列表的排序墅冷,都是按發(fā)送時間為基準(zhǔn),發(fā)送時間距離當(dāng)前時間越近排序越靠前或油。

這里面環(huán)信并沒有直接提供這樣的api寞忿。所以需要我們自己基于環(huán)信api做排序處理。

我把自己處理的代碼發(fā)出來装哆,List<UserFriend> dataList 是項目中調(diào)取本地好友接口獲取的好友列表。

EMClientMsgBiz clientBiz1 =newEMClientMsgBiz();

clientBiz1.setImAccount(o1.getFriendImAccount());

List lastMsgInfo1 = clientBiz1.getMessage(1);?

o1.getFriendImAccount()是該好友的環(huán)信賬號定嗓,然后 調(diào)取環(huán)信api蜕琴,getMessage(pagerNum),pagerNum代表獲取多少條數(shù)據(jù)宵溅,這里我們只需要獲取最新的消息記錄凌简,所以設(shè)置為1即可獲得與該好友的最后一條聊天EMMessage,如果沒有一個消息記錄恃逻,則conversation==null雏搂,所以new 一個集合返回藕施,否則有空指針異常。

獲取好友聊天記錄api

EMMessage? 環(huán)信聊天消息實體類凸郑,我們調(diào)用EMMessage.getMsgTime(裳食,獲取消息發(fā)送時間,然后把整個列表的會話排序即可芙沥。下面的方法便是比對消息發(fā)送時間的進行排序诲祸。Collections.sort(List list,Comparator c);是java.util中Collections類中的方法,不了解的可以去查看一下而昨。這樣好友消息會話列表的排序就處理好了

消息會話列表時間排序方法

接下來處理會話列表的顯示問題救氯。我這里的處理方式是在adapter里面處理的。

處理方式大同小異歌憨,通過UserFriend里面的friendImAccount着憨,調(diào)取環(huán)信api,獲取未讀消息數(shù)量getUnreadMsgCount务嫡,獲取最后消息發(fā)送時間getMsgTime(消息類型為long甲抖,時間戳為毫秒數(shù),如何顯示按需求處理)植袍,獲取最后消息發(fā)送內(nèi)容 EaseCommonUtils.getMessageDigest(lastMsgInfo1.get(0))惧眠。

好友消息列表顯示處理

EaseCommonUtils環(huán)信easeui demo里面的工具類,專門處理環(huán)信消息類型簡寫于个。

消息類型處理顯示

5.聊天界面消息發(fā)送氛魁,接收處理。

到了這一步厅篓,聊天準(zhǔn)備工作都做好了秀存,接下來可以選擇聊天對象,發(fā)送聊天消息和接收聊天消息羽氮。

上一步說到UserFriend或链,這個好友實體,是本地接口返回的數(shù)據(jù)档押,這是我自己項目中定義的變量澳盐,下面三個是自己定義的,接口不返回這些數(shù)據(jù)令宿,而是由環(huán)信api獲取到的叼耙,用于好友消息列表展示

接口服務(wù)返回實體變量定義

有了UserFriend這個實體,我們帶入聊天界面粒没,就可以通過好友的環(huán)信賬號筛婉,調(diào)用歷史消息記錄,未讀消息數(shù)量清零癞松,發(fā)送聊天消息環(huán)信api等等爽撒。接下來會講到入蛆。

EMClientChatBiz 是專門處理聊天界面調(diào)用環(huán)信api的業(yè)務(wù)類,進入聊天界面顯進行初始化硕勿,并且設(shè)置消息發(fā)送監(jiān)聽哨毁。OnSendMsgListener是自定義的回調(diào)接口。

chat聊天界面更新ui

emClientBiz.setChatUsernameId(userFriendInfo); 把好友的環(huán)信賬號傳入EMClientChatBiz首尼,這樣可以調(diào)用相關(guān)api方法挑庶。

5.1-EMClientChatBiz,聊天業(yè)務(wù)處理類软能,會一一詳細介紹

現(xiàn)在迎捺,發(fā)送各類消息,MessageInfo實體是本地定義的查排,根據(jù)發(fā)送內(nèi)容設(shè)置凳枝,并且轉(zhuǎn)換成相應(yīng)類型的EMMessage實體。

發(fā)送消息邏輯處理

各類消息的創(chuàng)建跋核,其中發(fā)送地理位置岖瑰,攜帶了定位截圖,是以EMMessage.createImageSendMessage()方法創(chuàng)建的砂代,因為環(huán)信api中創(chuàng)建位置消息蹋订,并不能攜帶圖片,因此才通過創(chuàng)建圖片消息刻伊,附帶自定義屬性將經(jīng)緯度等信息發(fā)送露戒。這個有點投巧,暫時沒想出好的辦法捶箱。

各類消息創(chuàng)建

首先設(shè)置消息發(fā)送監(jiān)聽智什,message.setMessageStatusCallback(newEMCallBack(){}); 每條消息的發(fā)送都需要設(shè)置消息監(jiān)聽,以便正確顯示發(fā)送狀態(tài)丁屎,顯示相應(yīng)的ui荠锭。

消息發(fā)送,并設(shè)立監(jiān)聽晨川,設(shè)置消息為發(fā)送中

消息發(fā)送证九,并設(shè)立監(jiān)聽,設(shè)置消息為發(fā)送中

根據(jù)發(fā)送監(jiān)聽回調(diào)修改消息狀態(tài)

修改消息狀態(tài)

EMCallBack共虑,其回調(diào)方法都是子線程愧怜,所以采用handler,更新ui

通過自定義監(jiān)聽看蚜,返回消息狀態(tài)叫搁,更新ui

發(fā)送消息處理完赔桌,接下來就是聊天界面接收消息處理了供炎。接收消息上面有說道渴逻,在首頁設(shè)置了消息接收的全局監(jiān)聽,現(xiàn)在我們就利用消息監(jiān)聽音诫,來處理聊天界面的消息接收夯缺。還是拿之前的圖來講瑟啃。ActivityTask,F(xiàn)ragmentTask是管理類,存放堆棧的實例俯抖,不理解的可以查看這篇博客

http://blog.csdn.net/u010635353/article/details/49681659

,sendDataToActivity類似于EventBus或者廣播通知牛欢,攜帶參數(shù)铭拧。

消息分發(fā)處理

這里主要將收到的消息傳遞到三個地方,如果當(dāng)前界面是在聊天界面庇茫,那么將EMMessage傳遞到聊天界面港粱。這里只介紹聊天界面的消息接收。

收到消息后旦签,取出EMMessage查坪,然后emMessage.getFrom(),獲取發(fā)送人的環(huán)信賬號宁炫,與當(dāng)前聊天對象的環(huán)信賬號比對偿曙,一致則加入消息列表,這樣處理主要防止好友消息亂入羔巢,比如你與A聊天望忆,好友B發(fā)你的消息你也可以接收到,如果正在聊天界面朵纷,不做處理炭臭,這條消息就會插入到聊天界面的消息列表中。

msgId也是同樣道理袍辞,如果出現(xiàn)同一時間收到多條重復(fù)消息鞋仍,那么他的msgId必定是一致的,所以也做了過濾處理搅吁。

消息接收處理

6.消息展示處理

文字消息獲取

圖片消息獲取

還可以獲取圖片寬高威创,這樣可以固定控件尺寸,imgBody.getWidth(),imgBody.getHeight()

位置消息獲取谎懦,由于位置消息是通過圖片類型發(fā)送的肚豺,因此接收還是圖片類型,但是先判斷自定義的屬性是否為null界拦,null會產(chǎn)生異常吸申,所以這個圖片消息不是位置消息。

語音消息??

isListened()該條消息是否已讀
獲取語音地址,點擊播放
播放時調(diào)用截碴,設(shè)置消息為已讀梳侨,一定要調(diào)用,否則不會更改未讀狀態(tài)

最后日丹,還有幾條實用的api走哺,可以使用。

指定會話消息未讀數(shù)清零
退出聊天界面哲虾,銷毀監(jiān)聽丙躏,與該好友的未讀消息清零
下拉加載更多,獲取消息聊天記錄
獲取聊天歷史
項目中用到的環(huán)信相關(guān)業(yè)務(wù)類

EMClientChatBiz:聊天界面使用束凑,發(fā)送消息

EMClientFriendBiz:添加好友晒旅,好友相關(guān)api

EMClientLoginBiz:登錄,退出環(huán)信賬號

EMClientMsgBiz:環(huán)信消息相關(guān)api汪诉,未讀敢朱,獲取消息數(shù),主要用于好友會話列表

EMClientReceiveBiz:聊天消息接收摩瞎,消息分發(fā)

這樣結(jié)合自身需求拴签,一個基礎(chǔ)聊天功能就出來了。還沒有使用過環(huán)信并且有這方面需求的的朋友可以自己動手試試旗们,有什么不明白的地方可以留言蚓哩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市上渴,隨后出現(xiàn)的幾起案子岸梨,更是在濱河造成了極大的恐慌,老刑警劉巖稠氮,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件曹阔,死亡現(xiàn)場離奇詭異,居然都是意外死亡隔披,警方通過查閱死者的電腦和手機赃份,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奢米,“玉大人抓韩,你說我怎么就攤上這事△蕹ぃ” “怎么了谒拴?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長涉波。 經(jīng)常有香客問我英上,道長炭序,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任苍日,我火速辦了婚禮少态,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘易遣。我一直安慰自己,他們只是感情好嫌佑,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布豆茫。 她就那樣靜靜地躺著,像睡著了一般屋摇。 火紅的嫁衣襯著肌膚如雪揩魂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天炮温,我揣著相機與錄音火脉,去河邊找鬼。 笑死柒啤,一個胖子當(dāng)著我的面吹牛倦挂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播担巩,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼方援,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了涛癌?” 一聲冷哼從身側(cè)響起犯戏,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拳话,沒想到半個月后先匪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡弃衍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年呀非,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镜盯。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡姜钳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出形耗,到底是詐尸還是另有隱情哥桥,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布激涤,位于F島的核電站拟糕,受9級特大地震影響判呕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜送滞,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一侠草、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧犁嗅,春花似錦边涕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宠蚂,卻和暖如春式撼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背求厕。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工著隆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人呀癣。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓美浦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親项栏。 傳聞我的和親對象是個殘疾皇子抵代,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容