經過連續兩個多月的努力(開發、除錯、測試、改bug),我們終於趕在中秋國慶之前能把全新的GGTalk Android版本獻給大家。
4年之前我們就推出了GGTalk Android的第一個版本,但是功能太簡單,介面很粗糙,程式碼也很糟糕。後面了,因為一直忙著做專案,也沒有太多時間去完善它。
很多使用GGTalk的朋友經常問新的Android版什麼時候出來,我們也是不好意思地一拖再拖,到了今年7月份,終於再也拖不下去了,必須要釋出一個功能相對完整的版本,才能對得住關注的朋友們。
終於,在今天GGTalk 7.0 對應的安卓全新版本終於和小夥伴們見面了,它與剛釋出的GGTalk 7.0 的PC客戶端可以是互通的,因此它當然也就可以與我們PC端相互通訊,相互聊天了。下面我們先來看看它的真面目吧!
( 想要直接下載GGTalk Android全新原始碼的朋友請點選:原始碼下載中心)
一、GGTalk 安卓版截圖
二、原始碼實現
接下來,我們概要的介紹一下GGTalk Android原始碼專案的結構,以及原始碼實現中比較重要和難以理解的部分,以方便大家能更快地上手GGTalk 安卓端原始碼。
1、專案結構
2、訊息傳送與接收
與服務端的通訊互動還是與PC端一致,都是採用的ESFramework的通訊框架來實現的。先建立一個客戶端客戶端引擎IRapidPassiveEngine,再呼叫引擎的initialize方法即可完成登入的操作。 程式碼如下
CustomizeHandler handler = new CustomizeHandler(); engine = RapidEngineFactory.CreatePassiveEngine(); engine.setEngineEventListener(GGApplication.getInstance()); engine.getBasicOutter().addBasicEventListener(GGApplication.getInstance()); LogonResponse resp = engine.initialize(getUserName, getPassWord, host, port, handler, getApplication());
登入成功後的訊息都是在GGApplication這個類中收到並處理,主要有如下2個回撥方法
/**
* 對方通過engin.sendMessage()方法傳送的訊息,會進入到該回撥中
* */
@Override
public void messageReceived(String sourceUserID, int messageType, byte[] message, String tag) {
switch (ContractType.getContractTypeByCode(messageType)) {
case CHAT:
try {
RichChatMessage richChatMessage = new RichChatMessage();
richChatMessage.deserialize(BufferUtils.wrappedBuffer(message));
EventBus.getDefault().post(new ChatEvent(tag, tag, richChatMessage, false));
GGApplication.getInstance().ringForMessage();
} catch (Exception e) {
e.printStackTrace();
}
break;
...
}
/**
* 對方通過engin.ICustomizeOutter.send()方法傳送的訊息,會進入到該回撥中
* */
@Override
public void handleInformation(String sourceUserID, int messageType, byte[] bytes) {
try {
switch (ContractType.getContractTypeByCode(messageType)) {
case UserStatusChanged:
UserStatusChangedContract userStatusChangedContract = new UserStatusChangedContract();
userStatusChangedContract.deserialize(bytes);
EventBus.getDefault().post(new UserStatusChanagedEvent(userStatusChangedContract.getUserID(), userStatusChangedContract.getStatus()));
break;
...
}
傳送訊息方式同樣有2種:1. 直接通過engin.sendMessage,2.通過ICustomizeOutter介面傳送 它們呼叫的方式都大同小異, 我們就以第一種方式來做介紹
public void sendChatMessage(String targetUserID, RichChatMessage message) { byte[] msg = null; try { msg = message.serialize(); } catch (Exception ee) { ee.printStackTrace(); } this.engine.sendMessage(null, ContractType.CHAT.getType(), msg, targetUserID); }
void sendMessage(String targerID, int type, byte[] data, String tag);
第一個引數 targerID 為接收者ID(null 表示接收者為服務端),第二個引數type 為訊息型別,第三個引數data 為訊息內容 序列化後的資料,第四個引數tag為附帶的字串(可為空字串)
3、主要控制元件介紹
(1)視訊控制元件:CameraSurfaceView、OMCSSurfaceView。
CameraSurfaceView:主要功能是顯示本機的預覽介面,通過ICamOpenOverCallback介面的回撥注入到OMCS框架中
@Override
public void cameraHasOpened() {
try {
//預覽camera所用holder,不可為null或是隱藏,否則不能從攝像頭獲取資料
SurfaceHolder holder = myView.getSurfaceHolder();
//觸發預覽事件
MultimediaManagerFactory.GetSingleton().startCameraPreview(holder);
} catch (Exception ex) {
ex.printStackTrace();
}
}
OMCSSurfaceView:主要功能是連線對方的攝像頭並顯示影像。使用起來也比較簡單,我們只需要通過setOtherVideoPlayerSurfaceView將它注入到攝像頭聯結器CameraConnector 中就可以了,當cameraConnector呼叫其beginConnect方法時就會自動去連線對方的攝像頭,並將影像內容顯示到OMCSSurfaceView控制元件上。
CameraConnector cameraConnector = new CameraConnector(); OMCSSurfaceView otherView = (OMCSSurfaceView) findViewById(R.id.opposite_surface); cameraConnector.setOtherVideoPlayerSurfaceView(otherView); cameraConnector.setVideoUniformScale(true,true); cameraConnector.beginConnect(uerid);
(2)音訊聯結器 MicrophoneConnector
這個就比較簡單了,只需呼叫其beginConnect方法即可,這樣就可以連線到對方的麥克風,監聽對方的語音
MicrophoneConnector microphoneConnector = new MicrophoneConnector(); microphoneConnector.beginConnect(uerid);
(3)語音訊息 AudioMessage
首先是初始化,並註冊播放的回撥方法
@Override protected void onResume() { super.onResume(); if (!MultimediaManagerFactory.GetSingleton().getAudioMessageController().isInitialized()) { MultimediaManagerFactory.GetSingleton().getAudioMessageController().initialize(); MultimediaManagerFactory.GetSingleton().getAudioMessageController().setAudioMessageHandler(GGApplication.getInstance()); MultimediaManagerFactory.GetSingleton().getAudioMessageController().getAudioMessagePlayer().setAudioPlayerCallback(this); } } //region IAudioPlayerCallback 播放回撥 @Override public void playFinished(AudioMessage message) { message.setAnimation(false); // Log.i("ChatLVAdapter", "playFinished:"+message); Message msg = mHandler.obtainMessage(1); mHandler.sendMessage(msg); } @Override public void playInterrupted(AudioMessage message) { message.setAnimation(false); // Log.i("ChatLVAdapter", "playInterrupted:"+message); Message msg = mHandler.obtainMessage(1); mHandler.sendMessage(msg); } //endregion
錄製和傳送語音訊息給對方,startCapture()方法開始採集,stopCapture()方法停止採集並返回已採集的AudioMessage物件,再通過send方法將 AudioMessage物件傳送給指定的好友。
if (event.getAction() == MotionEvent.ACTION_UP) {
if (SDKUtil.checkConnection()) {
AudioMessage message = MultimediaManagerFactory.GetSingleton().getAudioMessageController().stopCapture();
if (message != null) {
//沒有一秒不傳送
if (message.spanInMSecs > 1000) {
ChatInfo info = getChatInfo(GGApplication.getInstance().getMySelf().getUserID(), message, true);
addChatinfoAndDisplay(info);
MultimediaManagerFactory.GetSingleton().getAudioMessageController().send(message, TalkingID);
} else {
ToastUtils.showShort(ChatActivity.this.getApplication(), "時間太短!");
}
}
}
buttonSpeak.setText("按住說話");
//發出採集資料,並展現再介面中
} else if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (SDKUtil.checkConnection()) {
MultimediaManagerFactory.GetSingleton().getAudioMessageController().startCapture();
}
buttonSpeak.setText("鬆開結束");
}
接收語音訊息,需要實現 IAudioMessageHandler 介面 ,並呼叫setAudioMessageHandler 方法注入到OMCS框架中,當收到其他好友發來的語音訊息時就會觸發 handleAudioMessage,我們只需在該方法內做相關接收訊息的處理即可。
public interface IAudioMessageHandler {
void handleAudioMessage(AudioMessage var1);
}
@Override
public void handleAudioMessage(AudioMessage message) {
try {
EventBus.getDefault().post(new ChatEvent(message.creatorID, message.creatorID, message, false));
GGApplication.getInstance().ringForMessage();
} catch (Exception e) {
e.printStackTrace();
}
}
MultimediaManagerFactory.GetSingleton().getAudioMessageController().setAudioMessageHandler(GGApplication.getInstance());
語音訊息的播放和停止,通過getAudioMessagePlayer()獲取播放器,呼叫其play或stop 方法即可完成播放語音和停止播放的功能
IAudioMessagePlayer audioPlayer=MultimediaManagerFactory.GetSingleton().getAudioMessageController().getAudioMessagePlayer(); audioPlayer.play(audioMessage); audioPlayer.stop();
語音訊息頁面關掉時,記住要釋放語音訊息控制器,不然會一直佔用麥克風
MultimediaManagerFactory.GetSingleton().getAudioMessageController().dispose();
三、GGTalk Android 原始碼下載
最新原始碼下載以及部署說明文件,請轉到這裡。
注意:全新的GGTalk Android原始碼,要配合最新的GGTalk 7.0(服務端+PC端),才可以正常互通的。
________________________________________________________________________
歡迎和我探討關於GGTalk的一切,我的QQ:2027224508,多多交流!
大家有什麼問題和建議,可以留言,也可以傳送email到我郵箱:2027224508@qq.com。
如果你覺得還不錯,請粉我,順便再頂一下啊