項目下載地址:https://github.com/townkoim/Andorid_Goty_Im_
說明:項目爲一個商業項目、有在各大市場上線.裏面包含了,第三方登錄,分享,推送、即時IM聊天功能
Android加入即時聊天的功能.
對比了融雲、環信(主要對比了價格,小公司以經濟實惠爲主),最終還是選擇了親加、
第一步:進入http://www.gotye.com.cn/ 親加。註冊後臺並登陸,在註冊應用的時候,我這裏選擇“開放註冊”,開放註冊的好處就是,客戶端可以根據用戶的唯一ID,首次登陸親加後臺會自創建一個新用戶,而第二次登陸的時候就會使用上一次登陸創建之後的用戶名。
注意:一定要是客戶端提供的唯一ID
在創建成功之後..看一下應用,應用概況這一欄目,會顯示你註冊之後的APPKEY等相關信息,在IM用戶選項,會顯示,你已經註冊過的IM的用戶
下一步--http://www.gotye.com.cn/download.html,在這裏下載即時通訊API的安卓開發包(因爲沒接入語音通信,所以不需要下載語音通信API)
解壓之後,將相對應的Jar文件以及.so庫文件放到工程中,想對應的文件夾下
下一步:在adt-eclipse的安卓項目中集成親加(根據親加提供的api文檔:http://www.gotye.com.cn/docs/ime/android.html)
1、在Mainfest文件中加入以下權限
- <uses-permission android:name ="android.permission.INTERNET" />
- <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name ="android.permission.RECORD_AUDIO" />
- <uses-permission android:name= "android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name ="android.permission.ACCESS_WIFI_STATE" />
- <uses-permission android:name= "android.permission.CHANGE_NETWORK_STATE" />
- <uses-permission android:name ="android.permission.READ_PHONE_STATE" />
- <uses-permission android:name ="android.permission.READ_CONTACTS" />
2、在自定義的application中初始化親加,就是註冊親加到我的APP當中
- //使用您在親加管理平臺申請到的appkey初始化API,appkey如果爲空會返回參數錯誤。
- //context爲android上下文環境
- //下文提到的gotyeApi即爲GotyeAPI,後續不再贅述。
- GotyeAPI gotyeApi = GotyeAPI. getInstance();
- gotyeApi.init(MainActivity. this, "28683ef9-6295-4939-895f-96fbffa81c25" );
3、登錄註冊親加
說明:親加載進行改版之後,做了一個很大的變動,將所有的回調都放在了GotyeDelegate這個類當中,以前都是每個模塊都有每個模塊的接口(個人感覺,改版之後還沒有之前設計的合理,不利於程序的擴展,但是這樣又統一進行了封裝,利於程序的優化)
3.1 首先要進行註冊
註冊的接口爲:https://qplusapi.gotye.com.cn:8443/api/ImportUsers?email=登錄親加後臺的賬號&devpwd=登錄親加後臺的賬號&appkey=48377791-c431-4b0b-8372-26d0b95e7aa9&useraccount=?
PS:這一步應該由服務器來做批量導入用戶到親加,但是我這邊服務器沒有做,所以只能通過在APP端,用戶登錄服務器的時候,去親加註冊一個賬號,如果返回 {"errcode":200}字段,表示註冊成功,如果返回 {"failedUsers":["13798477145"],"errcode":403},表示已經註冊過了。
3.2登錄親加
- gotyeApi.addListener( delegate);
- //因爲在註冊的時候沒有假如密碼的參數,所以這裏登錄的時候密碼必須爲Null,不能爲空字符串,如需要密碼,在之前註冊的接口的用戶名後面加上&&userpwd=密碼
- gotyeApi.login( "13798477145", null);
- GotyeDelegate delegate = new GotyeDelegate(){
- public void onLogin( int code, com.gotye.api.GotyeUser user) {
- };
- };
根據重寫Login方法來得到登錄的回調,根據code來判斷是否登錄成功,可以參考api文檔中的GotyeStatusCode類判斷code的錯誤碼
至此--親加登錄就算完成了.登錄完成之後還有一部必須來進行實現:
根據login的方法,可以看到返回了一個GotyUser對象, 在這裏我們就可以改變這個User的一些屬性,比如設置用的頭像,設置用戶的暱稱,性別等
聊天模塊
聊天的唯一的身份就是通過此ID。
先說一下此處的改變:在以前的版本中,會有一個GotyMessage父類-下面對應GoteTextMessage(普通文本)、GotyeImageMessage(圖片)、GotyeRichTextMessage(聲音)、GotyeVoiceMessage(二進制文本)
,用來構成MVC模式中的Model體系、但是在這個版本中--就只有了一個GotyeMessage對象了。通過GotyeMessageType枚舉類,來判斷髮送或者接受的是什麼類型的消息
講解一下其中會用到的幾個關鍵的類
GotyeChatTarget 類---聊天對象的父類,聊天肯得要有一個對象,一個用戶是一個對象,一個聊天室也是一個對象、一個聊天羣組也是一個對象,
所以在不同的場合,需要GotyeChatTarget 對象的時候,根據業務需求來new 它的子類即可。
GotyeDelegate類:
下面來講解一下發送消息:
發送普通文本消息
//構建GotyeMessage對象,第一個參數爲發送者(可以省略),第二個參數爲接受者。
GotyeMessage msg = GotyeMessage. createTextMessage(new GotyeUser("自己的唯一ID" ), new GotyeUser("對方身份的唯一ID"), "要發送的文本" );
//發送消息
gotyeApi.sendMessage(msg);
圖片消息
創建圖片消息:
String imagePath = “/mnt/sdcard /icon.jpg”; ///< 設定原始圖片路徑,目前僅支持jpg
GotyeMessage message = GotyeMessage.createImageMessage(receiver, imagePath);
自定義數據消息
自定義數據消息 API支持發送用戶自定義數據:
byte[] userdata = “1234567890”.getBytes(); ///< 自定義數據內容不能超過4KB
GotyeMessage message = GotyeMessage.createUserDataMessage(receiver,userdata,len);
或者發送指定路徑文件裏的數據內容:
String path = “/mnt/sdcard /userdata.txt”; ///<文件內容不能超過4KB
GotyeMessage message = GotyeMessage.createUserDataMessage(receiver,path);
獲取自定義數據(如果存在): byte[] data = message.getUserData();
語音消息
開始錄音:在調用開始錄音的時候,會觸發GotyeDelegate類的onStartTalk(int code, boolean isrealtime, int targetType, GotyeChatTarget target)的回調方法,在這裏我們記下當前的時間
gotyeApi.startTalk(user,WhineMode.Default,maxDuration); ///< 單聊api,user爲聊天對象,WhineMode爲語音變聲參數,maxDuration爲時長(單位ms)
gotyeApi.startTalk(group,WhineMode.Default,maxDuration); ///< 羣聊語音消息
gotyeApi.startTalk(room,WhineMode.Default,realtime,maxDuration);
///<realtime如果爲true,則開始實時語音,聊天室所有用戶會收到onRealPlayStart的回調
gotyeApi.stopTalk();
結束錄音:在錄音結束的時候,會觸發GotyeDelegate類的onStopTalk(int code, GotyeMessage message,
boolean isrealtime)的犯法,在這裏,我們可以得到當前時間,減去剛纔在onstartTalk中記下的時間、判斷時間是否大於1S。(因爲我在實際開發中,必須大於1S才允許發送)
然後在這個回調的方法裏面。調用:
gotyeApi.sendMessage(message);///< 不調用發送消息方法消息是不會發送給對方的。但是該條語音消息會保存在本地。
OK,下面來看看接受消息:
接受主要是在onReceiveMessage(GotyeMessage message)方法中,在這裏,我們可以通過message.getType(),(通過枚舉
GotyeMessageType來判斷)
得到消息之後,我們就可以放到我們自己的ListView的適配器的數據源裏面去了
下面來講一下我的項目中微信聊天的佈局的實現:
我用一個ListView來顯示聊天界面的所有消息, 聊天界面的消息 自己發送的消息在界面的右邊,別人發送的消息在界面的左邊.
於是我通過重寫BaseAdapter的getViewTypeCount()方法,讓他return 2; 返回兩個佈局。
以及重寫getItemViewType(int position)方法, 在這個方法中,我通過ListView的數據源.getPosition(position) 方法,得到消息的實體類。 也就是GoteMessage對象。
在GotyeMessage對象中調用getSender()方法,得到這個用戶,和我自己剛登陸親加的時候的用戶信息進行匹配,如果相同,說明是我自己是發送者,那麼久return
右邊的佈局,反之...
如果接受的消息是語音或者圖片:
接收/下載 消息
下載消息:
gotyeApi.downloadMediaInMessage(message)///< 只有圖片消息和語音消息需要下載
注意: 新收到的消息如果是圖片或語音類型,圖片和語音文件並不隨消息一起到達接收方,需要手動調用該方法下載。
回調到GotyeDelegate 中的onDownloadMessage
void onDownloadMediaInMessage(int code, GotyeMessage message);
回調原型: void onDownloadMediaInMessage(int code, GotyeMessage message); /// <下載的消息,下載好的媒體文件在message.media.path或pathEx中