前言距離上次極光征文不知不覺(jué)已經(jīng)過(guò)了將近一年的時(shí)間,先感謝上次的征文比賽,通過(guò) 《我和 Android 推送的時(shí)間簡(jiǎn)史》 這篇文章獲獎(jiǎng),這次又厚著臉皮再次參與,因?yàn)轫?xiàng)目一直很忙,只得利用周末時(shí)間準(zhǔn)備 demo 素材和寫(xiě)文章,不好之處,多多見(jiàn)諒。 上一篇文章主要講述了 我跟 極光推送 的關(guān)系,以及簡(jiǎn)單的描述了其集成和使用,作為三個(gè)項(xiàng)目都在使用極光推送的我,對(duì)其了解也是相當(dāng)多的,當(dāng)然坑也踩了不少,不得不再次感謝大俠(極光技術(shù)人員)對(duì)我的幫助,雖然這一年沒(méi)有繼續(xù)接觸推送的業(yè)務(wù),但是當(dāng)我遇到困惑依然有問(wèn)必答,服務(wù)態(tài)度不容置疑! 在準(zhǔn)備參加征文時(shí)就在想應(yīng)該從哪個(gè)角度來(lái)寫(xiě)呢,正好之前跟前同事一起寫(xiě)了一個(gè)開(kāi)源項(xiàng)目 WeaponApp, 現(xiàn)在已經(jīng)有 800+ 的 star 了。 里面涉及的技術(shù)我就不一一闡述了,感興趣的話(huà)可以自行看一下,里面有一個(gè)模塊由我單獨(dú)負(fù)責(zé)- IM模塊,因?yàn)橐呀?jīng)集成了極光推送,考慮到成本和使用,最終選擇了極光IM,畢竟是以極光推送的大規(guī)模、高并發(fā)、穩(wěn)定的推送為技術(shù)基礎(chǔ),并繼承這些特性。那這篇文章就以我集成的經(jīng)歷和使用做個(gè)介紹,快速的實(shí)現(xiàn)具有 IM 功能的 APP。 展示這里只對(duì) IM 模塊功能做簡(jiǎn)單的演示,感興趣可以點(diǎn)擊 鏈接 進(jìn)行下載,如下 gif 圖: 基本的聊天功能已經(jīng)實(shí)現(xiàn),其中包括: 登錄、注冊(cè)、強(qiáng)踢和退登 個(gè)人信息查看和修改 查找好友并進(jìn)行聊天 群聊 個(gè)人中心展示 刪除會(huì)話(huà)和清空聊天記錄
后續(xù)會(huì)根據(jù)需要添加新的功能。 集成因?yàn)榍绊?xiàng)已經(jīng)集成了極光推送服務(wù),很多東西已經(jīng)不需要重復(fù)操作,只需要將 JMessage 相關(guān)的組件集成到項(xiàng)目中即可,詳情的步驟可直接參考官網(wǎng)。 1. 導(dǎo)入jmessage jar 包2. 在 AndroidManifest 中添加相應(yīng)的事件 沒(méi)了。。由此可以看出,由推送到 IM 過(guò)渡是多么流暢! 使用其實(shí)在使用的過(guò)程,無(wú)非是根據(jù)自己的業(yè)務(wù)需求,到 官網(wǎng) 查找 API 來(lái)實(shí)現(xiàn)自己想要的功能,那我就根據(jù)目前項(xiàng)目中有的功能進(jìn)行介紹。 注冊(cè)、登錄和退登這其實(shí)是用戶(hù)的信息管理,極光 IM 統(tǒng)一用 UserInfo 進(jìn)行管理,內(nèi)部包含了用戶(hù)的大部分信息: protected String userName; protected String nickname = ""; protected String avatarMediaID; protected String birthday = ""; protected String signature = ""; protected String gender = ""; protected String region = ""; protected String address = ""; protected String appkey = null; protected String notename = null; protected String noteText = null; protected Map<String, String> extras = new ConcurrentHashMap();
1. 注冊(cè) 一開(kāi)始打算自己寫(xiě)用戶(hù)服務(wù)器,事實(shí)上卻是由另一位開(kāi)發(fā)者完成了,但是考慮到 IM 的集成,用戶(hù)數(shù)據(jù)的遷移和轉(zhuǎn)存過(guò)程繁瑣,就干脆直接用極光的用戶(hù)接口,其實(shí)內(nèi)部的數(shù)據(jù)也確實(shí)很詳細(xì),還支持自定義字段,完全滿(mǎn)足日常需求。
JMessageClient.register(userName, password, new JMessageCallBack() { public void onSuccess() { registerSuccess(userName); public void onFailed(int status, String desc) {
注冊(cè)需要用戶(hù)名和密碼,注冊(cè)成功后通過(guò) setResult 的方法,將賬戶(hù)和密碼傳回登錄頁(yè)面。 2. 登錄 JMessageClient.login(userName, password, new JMessageCallBack() { public void onSuccess() { public void onFailed(int status, String desc) {
同注冊(cè)一樣,登錄也需要用戶(hù)名和密碼進(jìn)行登錄,如果格式有誤會(huì)直接觸發(fā) onFailed 回調(diào),彈出相應(yīng)的提示。成功后本地便會(huì)保存一個(gè) UserInfo 對(duì)象儲(chǔ)存用戶(hù)的信息。 3. 退登 極光支持主動(dòng)退出賬號(hào)的功能,即:
直接清除本地保存的用戶(hù)信息,同樣他支持多端同時(shí)在線(xiàn): 如果不打開(kāi)開(kāi)關(guān),另一臺(tái)設(shè)備登錄,會(huì)用 EventBus 發(fā)送 LoginStateChangeEvent,告知開(kāi)發(fā)者改賬號(hào)已在另一臺(tái)設(shè)備登錄,并且會(huì)攜帶三種狀態(tài): case user_password_change: forcedExit("賬號(hào)密碼被修改"); forcedExit("賬號(hào)在另一臺(tái)設(shè)備登錄"); forcedExit("賬號(hào)被刪除");
根據(jù)自己的需要進(jìn)行處理。 信息查看和修改1. 個(gè)人 自己的用戶(hù)信息其實(shí)是保存在本地的數(shù)據(jù)庫(kù)中,通過(guò)調(diào)用: mUserInfo = JMessageClient.getMyInfo();
獲取用戶(hù)信息,之前提過(guò) UserInfo 里面包含了用戶(hù)的所有數(shù)據(jù)。與之對(duì)應(yīng)的: JMessageClient.updateMyInfo(UserInfo.Field.gender, mUserInfo, new JMessageCallBack() { public void onSuccess() { public void onFailed(int status, String desc) {
這個(gè)就是修改自己信息的方法,通過(guò)傳入 UserInfo.Field 來(lái)區(qū)分修改屬性值。 2. 他人 如果需要查看好友的信息,可通過(guò) userName 進(jìn)行請(qǐng)求查詢(xún): JMessageClient.getUserInfo(userName, new GetUserInfoCallback() { public void gotResult(int status, String desc, UserInfo userInfo) { getViewModel().setUserInfo(userInfo); getViewModel().setError(desc);
具體的結(jié)果如下: 如果是個(gè)人信息,直接可以修改和退登,如果是他人只能查看并與其進(jìn)行聊天。 聊天終于到了核心的聊天功能,其實(shí)實(shí)現(xiàn)起來(lái)并不復(fù)雜,極光 IM 已經(jīng)給了豐富的 API 和使用說(shuō)明,足夠完成基本的需求。 1. 發(fā)消息 發(fā)消息,前提是需要構(gòu)建 Message 對(duì)象,以基礎(chǔ)文本為例: final Message message = mConversation.createSendTextMessage(sendContent); message.setOnSendCompleteCallback(new BasicCallback() { public void gotResult(int status, String desc) { MobclickAgent.onEvent(getContext().getApplicationContext(), "send_message", sendContent); getView().scrollToPosition(items.size() - 1); Toast.makeText(getContext(), desc, Toast.LENGTH_SHORT).show(); JMessageClient.sendMessage(message);
最終通過(guò) JmessageClient.sendMessage(message) 將消息發(fā)送出去。 2. 接收消息 他這里比較簡(jiǎn)單粗暴,直接使用 EventBus 進(jìn)行消息接收的回調(diào)。 他 jar 里集成了 EventBus,項(xiàng)目中也有了 EventBus,這一點(diǎn)還是蠻坑的。換想一下,這里也是為了方便接收,不然會(huì)有很多相互應(yīng)用,各種耦合,不過(guò)使用過(guò) EventBus 的小伙伴,應(yīng)該知道,如果維護(hù)不好 EventBus 會(huì)導(dǎo)致邏輯非常的混亂,維護(hù)和拓展異常困難。
* 目前只支持文字消息,后面再進(jìn)行優(yōu)化 public void onEventMainThread(MessageEvent event) { Message message = event.getMessage(); switch (message.getContentType()) { String userName = ((UserInfo) message.getTargetInfo()).getUserName(); if (TextUtils.equals(userName, mUserName)) { // 當(dāng)收到的消息是官方消息才進(jìn)行更新UI getViewModel().receiveMessage(message); LogUtils.i("office", message.getFromType());
根據(jù) contentType 區(qū)分消息實(shí)體的類(lèi)型,并做相應(yīng)的處理。 在需要接收消息的地方進(jìn)行事件的注冊(cè)和取消注冊(cè)。 JMessageClient.registerEventReceiver(this, 200); JMessageClient.unRegisterEventReceiver(this);
3. 單聊 這里引入一個(gè) Conversation 概念,當(dāng)你與他人聊天必然會(huì)建立會(huì)話(huà),那會(huì)話(huà)的消息和聊天的對(duì)象都會(huì)存在這個(gè)會(huì)話(huà)中,那單聊則通過(guò)傳入 userName 進(jìn)行聯(lián)系,由此可見(jiàn) userName 的唯一性和重要性。 因?yàn)閯傔M(jìn)去需要獲取歷史信息,所以通過(guò) conversion 獲取所有的消息,并展示在界面上。 mConversation = Conversation.createSingleConversation(userName); JMessageClient.getUserInfo(userName, this); if (mConversation == null) { msgCount = mConversation.getAllMessage().size(); List<Message> messagesFromNewest = mConversation.getMessagesFromNewest(curCount, LIM_COUNT); curCount = messagesFromNewest.size(); // 第一條消息是正序的,需要反轉(zhuǎn)一下 Collections.reverse(messagesFromNewest); for (Message message : messagesFromNewest) { MessageDirect direct = message.getDirect(); if (direct == MessageDirect.send) { addReceiverMessage(message);
4. 群聊 群聊與單聊有點(diǎn)類(lèi)似,不過(guò)建立會(huì)話(huà)的前提參數(shù)不是 userName, 而是 groupId 群的唯一標(biāo)識(shí) ID。 mConversation = Conversation.createGroupConversation(groupId); if (mConversation == null) { List<Message> messagesFromNewest = mConversation.getMessagesFromNewest(curCount, LIM_COUNT); curCount = messagesFromNewest.size(); Collections.reverse(messagesFromNewest); for (Message message : messagesFromNewest) { MessageDirect direct = message.getDirect(); if (direct == MessageDirect.send) { addReceiverMessage(message);
具體的代碼很相似,只是創(chuàng)建的過(guò)程不一樣,不再贅述。 總結(jié)前段時(shí)間王欣、字節(jié)跳動(dòng)等都推出社交軟件,不過(guò)在微信平臺(tái)被封殺,這點(diǎn)還是蠻狠的,不過(guò)另一方面反映出社交 聊天在各個(gè)行業(yè)應(yīng)用的廣泛,無(wú)論是金融、教育、銷(xiāo)售等軟件都需要一個(gè) IM 作為用戶(hù)與用戶(hù)、用戶(hù)和平臺(tái)之間的溝通橋梁,因此作為開(kāi)發(fā)者,還是要多多學(xué)習(xí)一下 IM 相關(guān)的知識(shí)。當(dāng)然自己能獨(dú)立完成最好,如果沒(méi)有經(jīng)歷或者暫時(shí)能力不夠,又或者公司急切需要集成 IM 功能,建議你可以考慮極光 IM 服務(wù),其推送服務(wù)做得還是蠻不錯(cuò)的,而且還在不斷的維護(hù)迭代中,有時(shí)間不妨嘗試一波吧! WeaponAppAPK下載 本文為極光征文參賽文章
|