• 中秋礼物!开源即时通信GGTalk安卓版全新源码!


           经过连续两个多月的努力(开发、调试、测试、改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。 

    如果你觉得还不错,请粉我,顺便再顶一下啊

  • 相关阅读:
    A/B test模块使用以及配置
    Linux下的tar压缩解压缩命令详解
    php mysql转义特殊字符的函数(转)
    cas server + cas client 单点登录 原理介绍
    php二维码的生产以及下载
    shiro 获取已经登录的用户
    Sql 根据多条件查询重复的数据 MySQL删除重复数据
    js base64 转PDF并下载,js baser64转图片并下载
    当同时安装Python2和Python3后,如何兼容并切换使用详解(比如pip使用)
    我的博客初始“话”
  • 原文地址:https://www.cnblogs.com/justnow/p/13744654.html
Copyright © 2020-2023  润新知