android Linphone SDK

2023-05-16

LinphoneLauncherActivity 是APP的入口组件,在这个组件里,它会启动LinphoneService这个后台服务,然后不断地判断这个后台服务是否已经启动完毕,如果已经启动完毕后,才让APP进入直接的功能组件LinphoneActivity。

        LinphoneService是标准的android后台服务,这个后台服务非常的关键,它需要完成的工作包括以下的内容。加载APP需要使用的资源,启动LinphoneManager这个APP的全局管理器,LinphoneManager 这个全局管理器会一方面管理LinphoneService 的实例,另一方面管理LinphoneCore这个核心实例,同时生成目前需要处理的事件通知的LinphoneCoreListenerBase实例并注册到LinphoneCore这个核心实例的事件监听器中。目前的LinphoneCoreListenerBase 实例只监听callState,globalState,registrationState这三个事件。如果这个时候有电话呼入,那么callState事件触发,callState事件当中state会是LinphoneCall.State.IncomingReceived,APP需要切换到电话呼入的操作界面。registrationState这个事件反馈的是用户的SIP账号到SIP服务器的注册状态,是成功注册还是注册失败等。

        LinphoneManager实现了LinphoneCoreListener, LinphoneChatMessage.LinphoneChatMessageListener这两个接口的部分方法,负责系统需要使用的资源的管理与初始化,管理着LinphoneCore的实例,负责了LinphoneCore的初始化和它的整个生命周期,同时又响应接收到文件消息与文件消息的响应,感觉它的整体职责是有点混乱的,可能作者开始是把它作为全局的统一资源管理器的,可是后来开发着开发着就什么东西都往里面放,就成了这样了。

        LinphoneActivity是整个APP的核心界面组件,它采用了容器的结构模式来组织它所要包含的各个Fragment。它维护了一个专门用于存放各个Fragment实例的Fragment列表。它采用的布局文件是main.xml,针对手机与平板电脑分别做了一套布局文件,呵呵。这个布局文件主要是分为上下两个部分,然后上边部分主要是菜单与状态栏,下边那部分再分为两大个部分,一个部分是Fragment的容器,另一个部分是代表功能模块的TAB形式的工具栏。LinphoneActivity也会生成一个LinphoneCoreListenerBase的实例并注册到LinphoneCore这个核心实例的事件监听器中,它监听的事件是messageReceived(有用户给自己发信息,这个信息可能是文件也可能是文本),registrationState,callState。当有电话呼入的时候,这个时间当前的组件也会接收到这个事件,然后将界面切换到CallIncomingActivity这个界面组件。

        CallIncomingActivity界面组件就是提供一个界面给用户选择接听还是挂断,并设置相关的接听参数。这个界面组件当中也生成一个LinphoneCoreListenerBase的实例并注册到LinphoneCore这个核心实例的事件监听器中,它监听的事件是callState,状态是State.CallEnd,这样在对方结束了电话呼入时好通知当前界面对方已经结束通话,不再呼入,那个APP应该结束当前界面,回到主界面状态。在CallIncomingActivity界面组件下,用户选择了接听电话,那么APP将切换到CallActivity这个界面组件下,同时判断当前用户是否接受视频电话,从而决定是视频通话,还是语音通话。

    CallActivity这个界面组件是通话界面,这个界面组件当中也生成一个LinphoneCoreListenerBase的实例并注册到LinphoneCore这个核心实例的事件监听器中,它监听的事件是callState,callEncryptionChanged。callState会通知新的来电呼入,对方暂停通话,对方更新通话设置等相应的事件消息,发便当前界面针对这些消息作出相应的反馈。这个通话界面主要是控制两个Fragment的动态切换,一个是语音通话的CallAudioFragment,在这个Fragment里,用户可以启用不启用麦克风和摄像头等。同时还可以向新的用户发起电话呼叫,不过从目前的界面看是只允许当前用户向某一个用户进行通话的,如果再邀请一个用户进入通话的话,它是把上一个通话的用户设置为暂停通话状态,然后当前用户与多个用户通话的话,就是不断地切换当前通话的用户。另一个是视频通话的CallVideoFragment,这个Fragment主要是展现两个视频流的窗口,一个是当前用户自己的视频在界面的右下角,另一个是通话对方的视频。默认是展现CallVideoFragment,当用户点击CallVideoFragment这个界面的时候,又切换回CallAudioFragment,这样用户才能看到功能栏方便操作。

        CallVideoFragment里有两个关键的SurfaceView,分别用户展现当前用户的视频和对方用户的视频。private SurfaceView mVideoView; 这个是对方用户的视频展现控件。private SurfaceView mCaptureView;这个是当前用户的视频展现控件。首先CallVideoFragment 会生成一个androidVideoWindowImpl的实例,这个实例再通过LinphoneManager.getLc().setVideoWindow(androidVideoWindowImpl)传入到linphone的核心当中,androidVideoWindowImpl的实例当中的相关事件监听器后续就能接收到内核的想着事件消息通知,从而将视频流传递到对应的SurfaceView当中,设置对方用户视频流到SurfaceView 当中的方法是LinphoneManager.getLc().setVideoWindow(vw),设置当前用户视频流到SurfaceView 当中的方法是LinphoneManager.getLc().setPreviewWindow(mCaptureView)。

        DialerFragment界面组件,提供一个拨号的键盘,用来输入需要呼叫的SIP号码,然后进行呼叫。拨号呼叫调用的是LinphoneManager.getInstance().newOutgoingCall(mAddress)这个方法,传递的参数是对方的SIP号码或是SIP地址。newOutgoingCall这个方法里会先对当前使用的网络类型进行检测,用的是LinphoneUtils.isHighBandwidthConnection()方法。然后最终调用CallManager.inviteAddress()方法进行呼叫,这个方法最终又调用的LinphoneCore.inviteAddressWithParams(lAddress, params)方法进行呼叫。当LinphoneActivity 订阅的callState事件的state == State.OutgoingInit || state == State.OutgoingProgress的时候,APP界面组件切换到CallOutgoingActivity,由这个界面来展现正在呼出的状态。

   CallOutgoingActivity这个界面组件,当中也生成一个LinphoneCoreListenerBase的实例并注册到LinphoneCore这个核心实例的事件监听器中,它监听的事件是callState,状态是State=Connected或是StreamsRunning的时候,说明对方接听成功,界面组件再切换回CallActivity,并显示是语音通话界面还是视频通话界面。

        CallManager是专门用来进行电话呼叫的管理者类,专门负责对进行呼叫,或是对当前进行的呼叫进行参数设置的更新。

        PreferencesListFragment和SettingsFragment界面组件是负责APP的参数设置,设置的参数非常的丰富,有账号,网络,音频,视频等。它们采用的是android框架自带的PreferenceScreen技术来建立整个参数设置的界面与功能,这样就省去了自己来做界面一个个实现相应的参数设置的功能。定义PreferenceScreen最关键的就是编写它对应的XML文件,这个XML文件编写好后,系统会根据它的内容来生成相应的设置界面,非常的方便,相应的技术点可以百度一下。一个PreferenceScreen里还可以嵌套多个PreferenceScreen,从而构建多层级的设置界面。系统里自带有多种类型的设置界面,如ListPreference,CheckBoxPreference等。但是这个PreferenceScreen它并不会保存相关的配置信息,所以这些配置参数的保存还是得由外部来进行保存,随后加载PreferenceScreen界面的时候,重新给里面的各个组件设置上相应的状态。目前在APP中是由LinphonePreferences这个类来负责了配置信息的保存的,而这个类又是依赖LpConfig这个具体负责读写配置文件的类来提供相应的功能,它真正的保存配置的文件是一个类似ini配置文件的文本文件,也就是讲linphone是自己实现的配置保存与读取功能,呵呵,没有用系统自带的,那我们也就沿用它的吧。默认的配置文件就在工程的res/raw下边,而PreferenceScreen配置文件就是在工程的res/xml下。

    HistoryListFragment是呼入呼出历史列表的展现界面组件,这些呼入呼出的历史记录数据LinphoneCore是直接自己用数据记录下来了的,所以APP不需要考虑记录这些信息,除非需要自己定制地保存这些信息,不想用LinphoneCore的。通过LinphoneManager.getLc().getCallLogs()可以获得呼入呼出的历史记录。

        LinphoneCore是整个linphone内核基于JNI的封装接口,LinphoneCoreImpl是linphone内核针对JAVA开发语言的封装。所有linphone内核的相关方法都是通过它来向android系统暴露。它里面有方法非常的多,这里需要关注几个关键的方法。

public void iterate();最为关键的主循环方法,应用程序应该经常调用它,因为它在后台会完成多件事情,如接收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地址或是SIP电话号码。

public boolean isIncall();当前是不是处在通话状态下,这个通话要么在是进行的,也可能是暂停的,但没有挂断,还是连接着的。

public void acceptCall(LinphoneCall aCall) throws LinphoneCoreException;接收正在向自己电话呼入的通话。

public void acceptCallUpdate(LinphoneCall aCall, LinphoneCallParams params) throws LinphoneCoreException;接收通话的另一方对当前通话配置的修改,这样就能保证自己的通话配置与对方的一至。

public void deferCallUpdate(LinphoneCall aCall) throws LinphoneCoreException;拒绝通话的另一方对当前通话配置的修改,这样自己的通话配置就不会自动被修改了。

public LinphoneCallLog[] getCallLogs();获得通话日志列表。

public LinphoneCallLog getLastOutgoingCallLog();获得最近的通话日志列表。

public boolean isNetworkReachable();获取当前网络连接状态是否可连接。

void muteMic(boolean isMuted);禁用或是启用麦克风。

void enableAdaptiveRateControl(boolean enable);启用或禁用自适应速率控制,这个是根据网络带宽来自动调整传输速率的,小心慎用。

void enableEchoCancellation(boolean enable);启用或禁用语音的回声消除,这个是利用降噪的,echo limiter是回声门限。

void enableSpeaker(boolean value);启用或禁用扬声器。

void setVideoDevice(int id);设置某个摄像头为当前使用的摄像头。

int getVideoDevice();获取摄像头列表。

boolean isVideoSupported();检测客户是否支持视频通话

void enableVideo(boolean vcap_enabled, boolean display_enabled);启用或禁用视频,可以设置自己与对方视频的状态,但是如果通话已经建立正在通话中,那么调用这个方法是没有任何作用的,它必须在通话前调用。

int updateCall(LinphoneCall call, LinphoneCallParams params);修改已经建立的通话的状态,但是这个并不是能改通话的所有状态,针对视频在通话中的设置修改是无效的,如通话中不能修改视频的分辨率。

int getUploadBandwidth();获取最大上行网络带宽,单位是kbit/s.

 

void setUploadBandwidth(int bw);设置最大上行网络带宽,单位是kbit/s。

 

int getDownloadBandwidth();获取最大下行网络带宽,单位是kbit/s。

 

void setDownloadBandwidth(int bw);设置最大下行网络带宽,单位是kbit/s.

boolean pauseCall(LinphoneCall call);暂停当前的通话。

 

boolean resumeCall(LinphoneCall call);恢复当前的通话。

 

boolean pauseAllCalls();暂停全部当前的通话。

void terminateAllCalls();结束全部的通话。

 

LinphoneCall[] getCalls();获取当前的全部通话。

void transferCall(LinphoneCall call, String referTo);把当前与自己连接的通话转接到别的用户那里,自己的通话结束掉。

 

void transferCallToAnother(LinphoneCall callToTransfer, LinphoneCall destination);把当前的通话转接到另一个正在进行的通话当中。

void setPlayFile(String path);设置播放给对方听的音乐,通话还在呼入的状态下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android Linphone SDK 的相关文章

  • 使用新语法应用 Android Gradle 插件

    如何使用新的 Gradle 插件语法应用 Android 插件 plugins id version 代替 buildscript dependencies classpath com android tools build gradle
  • 我在哪里可以获得可靠的熵来源(真正的随机性字节[])?

    目前 我正在寻找一种方法来增加随机性的质量 in my Android应用程序 纸牌游戏 之前 估计对于我的情况 52 排列 至少需要 226 位熵 226 个随机位 我打算用这个byte 作为种子SecureRandom SecureRa
  • 使用一个 apk 安装两个应用程序

    我有 2 个应用程序 1 内容提供者 2 使用此 ContentProvider 的应用程序 我需要使用单个 apk 文件安装这 2 个应用程序 我想在 Eclipse 中同时推送这两个应用程序 如果我将另一个项目添加到一个应用程序的构建路
  • 导入已经创建的sqlite数据库(xamarin)

    我正在使用 Xamarin 想知道如何导入我已经创建的 sqlite 数据库 到目前为止 我已将其添加到资产文件夹中 但不知道下一步从哪里开始 string localPath Path Combine System Environment
  • Android:我可以创建一个不是矩形的视图/画布吗?圆形的?

    我有一个圆形视图 悬停在主要内容上方 gt 从屏幕出来的 z 轴方向 当有人点击屏幕时 我希望选择主要内容或悬停在上方的视图 当它覆盖主视图时 到目前为止效果很好 我在透明画布上有一个圆形物品 这意味着您可以看到该圆圈之外的背景的所有内容
  • android中根据屏幕尺寸计算图像尺寸

    我正在尝试根据屏幕尺寸计算图像高度和宽度 我从后端获取 5 x 7 尺寸的图像 为了将像素乘以 72 进行转换 我有 360 X 504 尺寸的图像 对于 360 X 504 我的动态透明矩形区域将显示为 1 223 x 1 179 即 8
  • Android PhoneGap 插件,UI 选项卡栏,调整 WebView 大小

    我正在创建一个美味的 PhoneGap 插件 希望一旦它能被打开 准备好了 插件基本完成了 我只需要一个漂亮的用户界面 相互作用 简而言之 我想创建一个 本机 android 工具栏组件 如果您实现 PhoneGap UIControls
  • Android:如何使用后台线程?

    我开发了一个应用程序 它从互联网获取内容并相应地在设备的屏幕上显示它 该程序运行得很好 就是有点慢 加载并显示内容大约需要 3 4 秒 我想将获取内容并将其显示在后台线程中的所有代码放在一起 当程序执行这些功能时 我想显示一个进度对话框 你
  • 具有自定义源集的 Android Gradle 风格 - gradle 文件应该是什么样子?

    我有一个旧的 eclipse 项目 我已经转移到 android studio 并设置为使用flavor 它似乎工作得很好 直到我开始尝试在我的风格之间使用不同的 java 文件 我的项目设置是这样的 ProjectRoot acitonb
  • 如何向开发人员发送崩溃报告?

    我开发 Android 应用程序 但在某些情况下我的应用程序force close 如果出现以下情况 我如何向开发人员发送包含详细信息的电子邮件force close随时发生 The ACRA https github com ACRA a
  • 如何制作在手机和平​​板电脑上使用的响应式Android应用程序?

    我创建了一个 Android 应用程序 当我运行我的应用程序时Mobile Phone它工作得很好 但是当我跑进去时Tablet应用程序的布局已更改 那么 如何制作响应式Android应用程序用于Mobile并且也在Tablet 在Andr
  • Android 纹理仅显示纯色

    我正在尝试在四边形上显示单个纹理 我有一个可用的 VertexObject 它可以很好地绘制一个正方形 或任何几何对象 现在我尝试扩展它来处理纹理 但纹理不起作用 我只看到一种纯色的四边形 坐标数据位于 arrayList 中 the ve
  • 如何使用应用程序接口将蓝牙套接字传递给另一个活动

    因此 根据我收集的信息 套接字连接既不可序列化 也不可分割 但我需要将蓝牙连接传递给另一个活动 我不想作为中间人编写服务 所以请不要将此作为解决方案发布 我听说有一种方法可以使用自定义应用程序接口来传递这些类型的对象 但我一生都找不到这样的
  • TextInputLayout 对于在 EditText 中以编程方式给出提示没有效果

    我有一个 EditText 它的父级是 TextInputLayout 我试图以编程方式为 EditText 提供提示 不在布局中 在这种情况下 文本输入提示动画不起作用 它像简单的 EditText 一样工作 有人可以建议如何处理它吗 下
  • 即使 Android M 上的移动数据已打开(有连接),也可以通过 WiFi(无连接)发送请求

    我必须在没有互联网连接的情况下将 UDP 数据包发送到 WiFi 模块 配有自己的 AP 但是当我将手机连接到 AP 时 Android 会在移动数据接口上重定向我的数据包 因为它有互联网连接 我使用下面的代码来完成我的工作 但它似乎不适用
  • 屏幕开/关检测

    在这里 我试图确定屏幕是否打开 但按下电源锁定 解锁按钮时它似乎不起作用 应用程序运行没有错误 但 if else 中的代码似乎没有效果 Edited现在代码可以工作了 谢谢Olgun 但媒体播放器播放不会停止 并且每次在屏幕上 离屏时都会
  • SDK >=26 仍需要 mipmap/ic_launcher.png?

    在 Android 中 有两种指定启动器图标 可以说是应用程序图标 的方法 老 方式 在 mipmap 文件夹中指定不同的 png 文件 通常命名为 ic launcher png 但可以通过以下方式设置名称android icon mip
  • 由于“进程崩溃”,仪器运行失败。

    我想运行以下测试 package com xxx yyy import android content Context import androidx test InstrumentationRegistry import androidx
  • Android Gradle 同步失败:无法解析配置“:classpath”的所有工件

    错误如下 Caused by org gradle api internal artifacts ivyservice DefaultLenientConfiguration ArtifactResolveException Could n
  • Fragment 生命周期和在不存在的 Fragment 上调用 onCreate 的问题

    我正在 Android 中测试片段 并且片段生命周期有一些令人困惑的行为 我有一个活动 在横向和纵向模式下使用 xml 布局 我有一些代码可以访问在片段布局之一中定义的 EditText 对象 如果我以横向模式启动应用程序 一切都会正常 我

随机推荐