1、linphoneandroid工程解读LinphoneLauncherActivity 是APP的入口组件,在这个组件里,它会启动LinphoneService这个后台服务,然后不断地判断这个后台服务是否已经启动完毕,如果已经启动完毕后,才让APP进入直接的功能组件LinphoneActivity。 LinphoneService是标准的android后台服务,这个后台服务非常的关键,它需要完成的工作包括以下的内容。加载APP需要使用的资源,启动LinphoneManager这个APP的全局管理器,LinphoneManager 这个全局管理器会一方面管理LinphoneService 的实例
2、,另一方面管理LinphoneCore这个核心实例,同时生成目前需要处理的事件通知的LinphoneCoreListenerBase实例并注册到LinphoneCore这个核心实例的事件监听器中。目前的LinphoneCoreListenerBase 实例只监听callState,globalState,registrationState这三个事件。如果这个时候有电话呼入,那么callState事件触发,callState事件当中state会是LinphoneCall.State.IncomingReceived,APP需要切换到电话呼入的操作界面。registrationState这个事件反
3、馈的是用户的SIP账号到SIP服务器的注册状态,是成功注册还是注册失败等。 LinphoneManager实现了LinphoneCoreListener, LinphoneChatMessage.LinphoneChatMessageListener这两个接口的部分方法,负责系统需要使用的资源的管理与初始化,管理着LinphoneCore的实例,负责了LinphoneCore的初始化和它的整个生命周期,同时又响应接收到文件消息与文件消息的响应,感觉它的整体职责是有点混乱的,可能作者开始是把它作为全局的统一资源管理器的,可是后来开发着开发着就什么东西都往里面放,就成了这样了。 LinphoneA
4、ctivity是整个APP的核心界面组件,它采用了容器的结构模式来组织它所要包含的各个Fragment。它维护了一个专门用于存放各个Fragment实例的Fragment列表。它采用的布局文件是main.xml,针对手机与平板电脑分别做了一套布局文件,呵呵。这个布局文件主要是分为上下两个部分,然后上边部分主要是菜单与状态栏,下边那部分再分为两大个部分,一个部分是Fragment的容器,另一个部分是代表功能模块的TAB形式的工具栏。LinphoneActivity也会生成一个LinphoneCoreListenerBase的实例并注册到LinphoneCore这个核心实例的事件监听器中,它监听的
5、事件是messageReceived(有用户给自己发信息,这个信息可能是文件也可能是文本),registrationState,callState。当有电话呼入的时候,这个时间当前的组件也会接收到这个事件,然后将界面切换到CallIncomingActivity这个界面组件。 CallIncomingActivity界面组件就是提供一个界面给用户选择接听还是挂断,并设置相关的接听参数。这个界面组件当中也生成一个LinphoneCoreListenerBase的实例并注册到LinphoneCore这个核心实例的事件监听器中,它监听的事件是callState,状态是State.CallEnd,这样
6、在对方结束了电话呼入时好通知当前界面对方已经结束通话,不再呼入,那个APP应该结束当前界面,回到主界面状态。在CallIncomingActivity界面组件下,用户选择了接听电话,那么APP将切换到CallActivity这个界面组件下,同时判断当前用户是否接受视频电话,从而决定是视频通话,还是语音通话。 CallActivity这个界面组件是通话界面,这个界面组件当中也生成一个LinphoneCoreListenerBase的实例并注册到LinphoneCore这个核心实例的事件监听器中,它监听的事件是callState,callEncryptionChanged。callState会通知
7、新的来电呼入,对方暂停通话,对方更新通话设置等相应的事件消息,发便当前界面针对这些消息作出相应的反馈。这个通话界面主要是控制两个Fragment的动态切换,一个是语音通话的CallAudioFragment,在这个Fragment里,用户可以启用不启用麦克风和摄像头等。同时还可以向新的用户发起电话呼叫,不过从目前的界面看是只允许当前用户向某一个用户进行通话的,如果再邀请一个用户进入通话的话,它是把上一个通话的用户设置为暂停通话状态,然后当前用户与多个用户通话的话,就是不断地切换当前通话的用户。另一个是视频通话的CallVideoFragment,这个Fragment主要是展现两个视频流的窗口,
8、一个是当前用户自己的视频在界面的右下角,另一个是通话对方的视频。默认是展现CallVideoFragment,当用户点击CallVideoFragment这个界面的时候,又切换回CallAudioFragment,这样用户才能看到功能栏方便操作。 CallVideoFragment里有两个关键的SurfaceView,分别用户展现当前用户的视频和对方用户的视频。private SurfaceView mVideoView; 这个是对方用户的视频展现控件。private SurfaceView mCaptureView;这个是当前用户的视频展现控件。首先CallVideoFragment 会生成
9、一个androidVideoWindowImpl的实例,这个实例再通过LinphoneManager.getLc().setVideoWindow(androidVideoWindowImpl)传入到linphone的核心当中,androidVideoWindowImpl的实例当中的相关事件监听器后续就能接收到内核的想着事件消息通知,从而将视频流传递到对应的SurfaceView当中,设置对方用户视频流到SurfaceView 当中的方法是LinphoneManager.getLc().setVideoWindow(vw),设置当前用户视频流到SurfaceView 当中的方法是Linphon
10、eManager.getLc().setPreviewWindow(mCaptureView)。 DialerFragment界面组件,提供一个拨号的键盘,用来输入需要呼叫的SIP号码,然后进行呼叫。拨号呼叫调用的是LinphoneManager.getInstance().newOutgoingCall(mAddress)这个方法,传递的参数是对方的SIP号码或是SIP地址。newOutgoingCall这个方法里会先对当前使用的网络类型进行检测,用的是LinphoneUtils.isHighBandwidthConnection()方法。然后最终调用CallManager.inviteAd
11、dress()方法进行呼叫,这个方法最终又调用的LinphoneCore.inviteAddressWithParams(lAddress, params)方法进行呼叫。当LinphoneActivity 订阅的callState事件的state = State.OutgoingInit | state = State.OutgoingProgress的时候,APP界面组件切换到CallOutgoingActivity,由这个界面来展现正在呼出的状态。 CallOutgoingActivity这个界面组件,当中也生成一个LinphoneCoreListenerBase的实例并注册到Linpho
12、neCore这个核心实例的事件监听器中,它监听的事件是callState,状态是StateConnected或是StreamsRunning的时候,说明对方接听成功,界面组件再切换回CallActivity,并显示是语音通话界面还是视频通话界面。 CallManager是专门用来进行电话呼叫的管理者类,专门负责对进行呼叫,或是对当前进行的呼叫进行参数设置的更新。 PreferencesListFragment和SettingsFragment界面组件是负责APP的参数设置,设置的参数非常的丰富,有账号,网络,音频,视频等。它们采用的是android框架自带的PreferenceScreen技术
13、来建立整个参数设置的界面与功能,这样就省去了自己来做界面一个个实现相应的参数设置的功能。定义PreferenceScreen最关键的就是编写它对应的XML文件,这个XML文件编写好后,系统会根据它的内容来生成相应的设置界面,非常的方便,相应的技术点可以XX一下。一个PreferenceScreen里还可以嵌套多个PreferenceScreen,从而构建多层级的设置界面。系统里自带有多种类型的设置界面,如ListPreference,CheckBoxPreference等。但是这个PreferenceScreen它并不会保存相关的配置信息,所以这些配置参数的保存还是得由外部来进行保存,随后加载
14、PreferenceScreen界面的时候,重新给里面的各个组件设置上相应的状态。目前在APP中是由LinphonePreferences这个类来负责了配置信息的保存的,而这个类又是依赖LpConfig这个具体负责读写配置文件的类来提供相应的功能,它真正的保存配置的文件是一个类似ini配置文件的文本文件,也就是讲linphone是自己实现的配置保存与读取功能,呵呵,没有用系统自带的,那我们也就沿用它的吧。默认的配置文件就在工程的res/raw下边,而PreferenceScreen配置文件就是在工程的res/xml下。 HistoryListFragment是呼入呼出历史列表的展现界面组件,这
15、些呼入呼出的历史记录数据LinphoneCore是直接自己用数据记录下来了的,所以APP不需要考虑记录这些信息,除非需要自己定制地保存这些信息,不想用LinphoneCore的。通过LinphoneManager.getLc().getCallLogs()可以获得呼入呼出的历史记录。 LinphoneCore是整个linphone内核基于JNI的封装接口,LinphoneCoreImpl是linphone内核针对JAVA开发语言的封装。所有linphone内核的相关方法都是通过它来向android系统暴露。它里面有方法非常的多,这里需要关注几个关键的方法。public void iterate
16、();最为关键的主循环方法,应用程序应该经常调用它,因为它在后台会完成多件事情,如接收SIP指令,注册,认证,超时检测等,它必须要运行在LihpnoCore其它的方法所运行的线程里,说白了就是要保证LinphoneCore的方法运行在一至的线程里,不然就出错了。public LinphoneCall invite(LinphoneAddress to)throws LinphoneCoreException;向对方发起一个电话呼叫请求。public void terminateCall(LinphoneCall aCall);结束当前的电话呼叫。public void declineCall(LinphoneCall call, Reason reason);直接挂断当前正在呼入的电话请求。public LinphoneCall getCurrentCall();获取当前正在进行电话通话的实例。public LinphoneAddress getRemoteAddress();获取当前通话下对方的SIP
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1