android 通话涉及的类分析

Android音频焦点详解(下)——源码详解 耽搁了几天,最近一直在忙找工作的事情,今天把这篇文章补上。 本文基于Android7.1.1版本进行分析,主要涉及以下几个文件: 1 AudioManager –> /frameworks/base/media/java/android/media/ 2 AudioService –> /frameworks/base/services/core/java/com/a 阅读详情
通话涉及的类分析

1 OutgoingCallBroadcaster.java
点击拨号盘拨打按钮后,进入通话的Phone包。此时首先进入的函数是OutgoingCallBroadcaster.java,该类是一个Activity。
由activity的生命周期可知,第一次进入时应调用onCreate()函数。(在该类中也只实现了这个函数。)解析一下这个函数:
1.1) 首先获取Intent对象,获取拨出的号码。
1.2) 接着判断号码是否为紧急号码,如果是紧急号码,将callNow变量赋值为true,启动InCallScreen,并发送广播。而在receiver里面判断callNow为ture就直接finish,而不再重复启动InCallScreen;如果不是紧急号码,将callNow变量赋值为false,发送广播“Intent.ACTION_NEW_OUTGOING_CALL”。

2 OutgoingCallReceiver.java
广播发送后OutgoingCallReceiver将会收到该息。该类是一个内部类,在类OutgoingCallBroadcaster里面,作用是接收OutgoingCallBroadcaster发送的广播,判断是否已经启动InCallScreen。没有启动的话就进行一些初始化,如:对OTA进行初始化。接收到广播之后,从Intent里面取出电话号码及其URi。然后,设置Intent为ACTION_CALL,并带上号码和uri。启动InCallScreen。关闭该Activity。
OTA:Over-the-Air Technology空中下载技术,是通过移动通信(GSM或CDMA)的空中接口对SIM卡数据及应用进行远程管理的技术。空中接口可以采用WAP、GPRS、CDMA1X及短消息技术。OTA技术的应用,使得移动通信不仅可以提供语音和数据服务,而且还能提供新业务下载。
GSM:Global System for Mobile Communications,中文为全球移动通讯系统,俗称"全球通"。
CDMA:Code Division Multiple Access,又称码分多址,是在无线通讯上使用的技术,CDMA允许所有的使用者同时使用全部频带(1.2288Mhz),并且把其他使用者发出的讯号视为杂讯,完全不必考虑到讯号碰撞 (collision) 的问题。CDMA的优点包括:CDMA中所提供的语音编码技术,其通话品质比目前的GSM好,而且可以把用户对话时周围环境的噪音降低,使通话更为清晰。

3 InCallScreen.java
该类extends了Acitivity,并且implements了OnClickListener,OnTouchListener和OnQueryCompleteListener。该类主要是负责通话的那一个界面,并且还负责菜单项各种按键事件和触摸时间的处理。同时本类还复写的finish()方法,所以一般不会被finish掉,调用这个方法时它又把自己放回栈中。InCallScreen可以接收这个Intent并启动。
3.1) onCreate(第一次)
3.1.1) callScreenOnCreate获得通话界面被创建的时间。
3.1.2) PhoneApp唤醒后台的服务程序。
3.1.3) 判断当前的通话状态(IDLE =没有通话行为,RINGING =正在通话或呼叫等待,OFFHOOK = The phone is off hook. At least one call exists that is dialing, active or holding and no calls are ringing or waiting.),如果正在通话,不会出现键盘锁。接着设置mPhone and mForegroundCall/mBackgroundCall/mRingingCall。
3.1.4) getBluetoothHandsfree设置蓝牙耳机,如果存在蓝牙耳机,则安装该设备。
3.1.5) initInCallScreen加载各种view组建。
3.1.6) 对通话的各种状态进行广播。(registerForPreciseCallStateChanged,registerForDisconnect,registerForMmiInitiateregisterForMmiComplete,registerForCallWaiting,registerForSuppServiceFailed,registerForCdmaOtaStatusChange)
3.1.7) internalResolveIntent判断是否使用了OTA技术,通过该判断设置通话界面的样式。
3.1.8) callScreenCreated记录通话界面创建完成后的时间
3.2) onNewIntent(非第一次)。
我们重新启动一个Intent时调用该函数。由于我们围绕唯一的一个InCallScreen实例来完成通过的这个过程,那么除了第一次被创建的InCallScreen,只要有来电或者去电,该程序就会发生。如果InCallScreen已经在前台,该程序也会发生。
3.2.1) setIntent保存该Intent,以至于将来我们可以获得该intent。
3.2.2) internalResolveIntent
3.3) onResume
进行一些初始化操作,如:获取一个PhoneApp对象,解开Keyguard Notification的statusBar给Disable。还内置了一个Handler可以回调处理一些事件,比如:PHONE_STATE_CHANGED,PHONE_DISCONNECT,EVENT_HEADSET_PLUG_STATE_CHANGED。同时有一个独立的BroadcastReceiver处理ACTION_HEADSET_PLUG,比如插入耳机等。
3.3.1) 首先对锁屏情况下的来电除了处理。
3.3.2) disableStatusBar当正在通话界面时,使得状态栏可用。
3.3.3) setIgnoreTouchUserActivity忽略通话过程中无意的触碰事件,使得这些无意的触碰不会阻止设备进入休眠。
3.3.4) registerReceiver监听广播
3.3.5) startDialerSession当在前台是,保持一个dialer session。首先判断时候需要播放本地铃声,如果需要,则判断双音多频是否可用,如果可用,则创建一个声音播放器。
3.3.6) isBluetoothAudioConnected做一个是否蓝牙连接的判断。
3.3.7) 如果是cdma通话,则初始化OTA状态,进而如果是采用了OTA,则设置InCallScreenMode为OTA通话模型。
3.3.8) clearDisconnected在检查该通话状态之前,切断其他网络连接。
3.3.9) syncWithPhoneState同步通话界面与Phone的当前状态。如果没有同步成功,则dismissAllDialogs();结束当前的所以通话,endInCallScreenSession();关闭通话界面的显示。
3.3.10) updateWakeState设置基于当前Phone的唤醒状态和屏幕超时,以及通话界面的当前状态。
3.3.11) enableTouchLock当onresume时“触摸锁“叠加是不可见的,尤其是这个检查可确保用户通话按MUNU来唤醒屏幕后将不会被锁。但如果拨号盘是打开的,而又需要通话计时,则造就了“触摸锁“覆盖。

4 Profiler.java
该类对通话各个时间点进行记录。
static long sTimeCallScreenRequested;//通话界面被请求的时间
static long sTimeCallScreenOnCreate;//通话界面被创建的时间
static long sTimeCallScreenCreated;//通话界面创建完成后的时间
static long sTimeIncomingCallPanelRequested;//正在通话时,通话界面被请求的时间
static long sTimeIncomingCallPanelOnCreate;//正在通话时,通话界面被创建的时间
static long sTimeIncomingCallPanelCreated;//正在通话时,通话界面创建完成后的时间

5 PhoneUtils.java
负责Phone对象的生成,主要调用phone.getForegroundCall(),phone.getBackgroundCall(),phone.getRingingCall(),phone.dial()。
5.1) placeCall(Phone phone, String number, Uri contactRef)
拨打传入的电话号码,该函数被InCallScreen中的placeCall调用。
参数phone手机对象;参数number用户要拨打的号码;参数contactRef要么是“tel:”,要么是“content://contacts”,取决于通话初始化,该参数引发呼叫;返回CALL_STATUS_DIALED,CALL_STATUS_DIALED_MMI,或CALL_STATUS_FAILED。
5.2) placeCallVia(Context context,Phone phone,String number,Uri contactRef,Uri gatewayUri)
使用第三方提供的网关拨打号码,该函数被InCallScreen中的placeCall调用。如果电话号码是紧急号码,GSM MMI码或者CDMA码则不能被呼叫。如果连接成立,这个方法发出一个同步调用阻止查询来电信息,使本地采用异步查询。
参数phone手机对象;参数context执行CallerInfo查询;参数number用户要拨打的号码,如果号码不能建立连接,则仅被用于建立电话卡,并更新通话记录;参数contactRef要么是“tel:”,要么是“content://contacts”,该参数引发呼叫;参数gatewayUri用于设置连接的地址;返回CALL_STATUS_DIALED或CALL_STATUS_FAILED。

6 PhoneApp.java
该类是一个普通的java类,主要负责Phone对象顶层应用的生成。这是一个虚拟的Phone对象,它从framework层取得一个Phone对象。该类继承自Application,同时能常驻内存,他和PhoneUtils一起处理电话操作。在oncreate方法里面进行各种全局的初始化:获取Phone对象 NotificationMgr对象,PowerManager对象,SimCard对象等。同时内置的Handler可以回调处理各种事件,如:EVENT_SIM_ABSENT,EVENT_SIM_NETWORK_LOCKED,EVENT_UPDATE_INCALL_NOTIFICATION等。

7 CallNotifier.java
监听Phone状态的改变和来自telephony层各种事件,并触发任何有关的UI行为(如开始的铃声和来电的用户界面,打在通话音,更新通知,写呼叫记录条目等)。
7.1) 在构造函数中,实现
mPhone.registerForNewRingingConnection(this, PHONE_NEW_RINGING_CONNECTION, null);/*当有新来电或等待连接时Notifies。收到的讯息是:Message.obj将是一个AsyncResult,AsyncResult.userObj=obj,AsyncResult.result=a Connection。因为这个消息已经过时,所以通过检测Connection.isRinging()以确保连接有效。如果Connection.isRinging()为true,那么Connection.getCall()==Phone.getRingingCall()*/
mPhone.registerForPreciseCallStateChanged(this, PHONE_STATE_CHANGED, null);/*为通话状态的改变注册notification。通过调用PreciseCallState以获取更准确的通话状态。*/
mPhone.registerForDisconnect(this, PHONE_DISCONNECT, null);/*当由于本地或远程电话挂断或者出现错误挂断通话时Notifies。收到的讯息是:Message.obj will be an AsyncResult,AsyncResult.userObj = obj,AsyncResult.result = a Connection object that is no longer connected.*/
mPhone.registerForUnknownConnection(this, PHONE_UNKNOWN_CONNECTION_APPEARED, null);/*当以前未跟踪non-ringing/waiting连接时Notifies。这可能是由于一些其他实体(如SIM卡应用)发起呼叫。*/
mPhone.registerForIncomingRing(this, PHONE_INCOMING_RING, null);/*当有来电话响铃时Notifies。收到的讯息是:Message.obj will be an AsyncResult,AsyncResult.userObj = obj,AsyncResult.result = a Connection.*/
另外如果是CDMA通讯类型,还执行:
mPhone.registerForCdmaOtaStatusChange(this, EVENT_OTA_PROVISION_CHANGE, null);/*当CDMA OTA提供者位置改变时注册notification*/
mPhone.registerForCallWaiting(this, PHONE_CDMA_CALL_WAITING, null);/*当CDMA呼叫等待时注册notification*/
mPhone.registerForDisplayInfo(this, PHONE_STATE_DISPLAYINFO, null);/*为来自网络显示信息通知注册。Message.obj将包含一个AsyncResult。AsyncResult.result将是一个SuppServiceNotification实例。*/
mPhone.registerForSignalInfo(this, PHONE_STATE_SIGNALINFO, null);/*为来自网络的信号信息通知注册。Message.obj将包含一个AsyncResult。AsyncResult.result将是一个SuppServiceNotification实例。*/
mPhone.registerForInCallVoicePrivacyOn(this, PHONE_ENHANCED_VP_ON, null);/*当sInCall VoicePrivacy可用时注册notification*/
mPhone.registerForInCallVoicePrivacyOff(this, PHONE_ENHANCED_VP_OFF, null);/*当sInCall VoicePrivacy不可用时注册notification*/
mPhone.registerForCdmaFwdBurstDtmf(this, PHONE_CDMA_FWD_BURST_DTMF, null);/*为 CDMA Forward Burst DTMF的事件通知设置处理程序*/
mPhone.registerForCdmaFwdContDtmfStart(this, PHONE_CDMA_FWD_CONT_DTMF_START, null);/*为 CDMA Forward Burst DTMF启动的事件通知设置处理程序*/
mPhone.registerForCdmaFwdContDtmfStop(this, PHONE_CDMA_FWD_CONT_DTMF_STOP, null);/*为 CDMA Forward Burst DTMF停止的事件通知设置处理程序*/
如果是GSM类型,则执行:
mPhone.registerForRingbackTone(this, PHONE_RINGBACK_TONE, null);/*当带外回铃音(专业术语CRBT:COLOR RING BACK TONE,回铃音定义:当别人打电话给您时,他(她)听到的声音叫做回铃音。回铃音是指拨打电话的呼叫方所听到的对方电话的声音,当拨通电话时听到通话音,通常是长音;而当对方占线时则听到忙音,声音短促,有时,忙音会变成人声语音提示。)时Notifies。收到的讯息是:Message.obj将是一个AsyncResult,AsyncResult.userObj=obj,AsyncResult.result=true表示开始播放回铃音;=false表示停止。*/
mPhone.registerForResendIncallMute(this, PHONE_RESEND_MUTE, null);/*为复位上行静音状态成上行音频注册处理程序。*/
7.2) 整个类由函数handleMessage串起来。

为了您的安全,请只打开来源可靠的网址

打开网站    取消

来自: http://hi.baidu.com/wentaokou/blog/item/816c6844d469aa32cefca31b.html

Android 通话流程相关分析 if (!} else { 阅读详情

相关推荐

android 通话的log分析,Android-9种通话状态(精确)

一.介绍在应用层监听通话状态只有三种,从TelephonyManager.java中注释可知这三种状态含义如下:CALL_STATE_IDLE 空闲态(没有通话活动)CALL_STATE_RINGING 包括响铃、第三方来电等待CALL_STATE_OFFHOOK 包括dialing拨号中、active接通、hold挂起等由上可知,active接通状态没有单独给出,所以我们无法得知电话是否接通了,...

weixin_42395498的博客 2050

Android-9种通话状态(精确)

1.监听9种通话状态 TelephonyManager telM = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); telM.listen(new PhoneStateListener(){ /** * 当有精确通话状态时回调 * Callback invoked when prec

http://lioil.win 1万+

android 通话记录分析,Android中联系人和通话记录详解(1)

由于项目开发需要用到手机联系人和通话记录的详细信息,于是对联系人和通话记录的表及各字段以及具体实现做了详细分析。首先,通过模拟器或者Root过的手机,在/data/data/com.android.providers.contacts/database文件夹下得到contacts2.db数据库文件,然后用SQLite Expert软件打开,可以看到有如下表:其中,通话记录有关的表为:calls;...

weixin_29870701的博客 1858

Android电话流程

Android电话流程1 OutgoingCallBroadcaster.java点击拨号盘拨打按钮后,进入通话的Phone包。此时首先进入的函数是OutgoingCallBroadcaster.java,该是一个Activity。由activity的生命周期可知,第一次进入时应调用onCreate()函数。(在该中也只实现了这个函数。)解析一下这个函数:1.1) 首先获

erik3699298的专栏 3820

Android7.0 拨号流程源码分析

1. 应用进程 从点击拨号按钮流程说起 packages/apps/Dialer/src/com/android/dialer/dialpad/DialpadFragment.java @Override public void onClick(View view) { int resId = view.getId(); if (resId == R.id.dialpad_flo...

此男子淡漠 1914

android呼叫流程源码分析

2. ICS Android 4.2 呼叫流程 2.1 呼叫请求 2.1.1 拨号请求(Contact) 我们从拨号盘开始分析呼叫流程。我们知道,输入一个号码,点击Call按钮,就开始触发了一个呼叫,然后将进行号码检查、判断,网络状态检查等工作,代码逐步向下调用,经过telephony、ril,再通过AT指令,让modem完成信道请求、连接和相应信令处理。   1)阶

4707

android 电话状态的监听(来电和去电) PhoneStateListener和TelephonyManager

今天的程序可以实现电话状态改变时启动(来电、接听、挂断、拨打电话),但是暂时没法实现拨打电话时判断对方是否接听、转语音信箱等。Android电话状态改变是会发送actionandroid.intent.action.PHONE_STATE的广播,而拨打电话时会发送actionandroid.intent.action.NEW_OUTGOING_CALL的广播,但是我看了下开发文档,暂时没发现

4980

android电话实现分析

1 OutgoingCallBroadcaster.java 点击拨号盘拨打按钮后,进入通话的Phone包。此时首先进入的函数是OutgoingCallBroadcaster.java,该是一个Activity。 由activity的生命周期可知,第一次进入时应调用onCreate()函数。(在该中也只实现了这个函数。)解析一下这个函数: 1.1) 首先获取Intent对象,获取拨出的号...

iteye_3818的博客 356

深入分析Android 5.0 InCallUI源码实战

InCallUI由几个关键的组件构成,包括和等。每一个组件都有特定的职责,共同确保电话功能的顺畅运行。接下来的章节将逐一介绍这些组件,并分析它们的工作原理。的用户界面是提供给用户交互的直接媒介,其设计应该直观、简洁且功能齐全。布局通常包括通话状态显示、控制按钮、通话记录等。界面设计通常使用XML布局文件来定义,例如:<TextView<Button-- 其他界面元素 -->在上述布局代码中:用于灵活地布置界面元素。TextView。

weixin_36311421的博客 887

android N 拨打电话流程(MO)

本流程图基于MTK平台 Android N,拨打的普通电话,本流程只作为沟通学习使用整体流程图流程中部分重点知识packages-apps目录 dialer应用的DialpadFragment.onClick中,通过用户输入号码并点击拨号按钮(R.id.dialpad_floating_action_button)发起MO 在handleDialButtonPressed方法里面会判断输入框中是否含

Yigit_dev的博客 1万+

通话涉及分析

1 OutgoingCallBroadcaster.java 点击拨号盘拨打按钮后,进入通话的Phone包。此时首先进入的函数是OutgoingCallBroadcaster.java,该是一个Activity。 由activity的生命周期可知,第一次进入时应调用onCreate()函数。(在该中也只实现了这个函数。)解析一下这个函数: 1.1) 首先获取Intent对象,获取拨出的号

androidboy365的专栏 591

Android 电话涉及到的几个备注

    顶层代码:PhoneApp.java, extends Application, 说明这一个应用程序,此中会启动一个InCallScreen。     对于通话,也有可能其他情况引起通话,如从电话本中拨号,或从短信中拨号,这时主是通过OutgoingCallBroadcaster发起通话广播 OutgoingCallBroadcaster.java, extends Activity, 有一个内部OutgoingCallReceiver, 其注释为:如果广播还未被取消,终止NEW_OUTGOI

Askeyes的专栏 3185

android-hfpclient-电话功能

HeadsetClientService: connect –连接 电话操作和状态 bluedroid 对应的电话操作 typedef enum { BTHF_CLIENT_CALL_ACTION_CHLD_0 = 0,//held call release Releases all held calls or sets User Determined User Bus...

nilingxi的专栏 1891

基于Android11的拨号流程分析

拨号分析也就是数据业务如何建立起来,本文档用于分析及总结拨号的流程,用于后面快速定位RIL拨号这块出现的问题。

teti3231052的博客 3553

Android电话拨打流程源码分析

前面分析电话拨号界面及电话呼叫界面,由于Android电话Phone设计的很复杂,因此先从UI层入手分析。想要了解Android电话拨号UI,请查看Android电话拨号UI分析电话拨号UI在Contacts包中。想要了解Android电话呼叫UI,请查看Android电话Phone UI分析,该UI在Phone包中,了解完电话想要UI后,还必须首先了解Android的Phone设计框...

架构设计 1022

android12的拨号流程

1.点击拨号 /android/packages/apps/Dialer/java/com/android/dialer/dialpadview/DialpadFragment.java @Override public void onClick(View view) { int resId = view.getId(); //点击拨号 if (resId == R.id.dialpad_floating_action_button) { view.perform

qq_41285455的博客 2986

PhoneAccount流程解析(SIM卡管理器)拨号过程中解析PhoneAccount

刚开始看拨号流程是 总是出现PhoneAccount和PhoneAccountHandler,一直不知道是干嘛使的。所以今天写一篇文章来记录一下免得忘了。 在网上找了挺多资料,然后对照代码看了一遍。 PhoneAccount的作用 : PhoneAccount就是在拨打电话和来电过程中使用哪一张SIM卡,哪一个SIP账号,从代码里面可以看出来他本身是实现了Parcelab...

达帮主 6965

Android 10 拨打电话流程

接续上一章节,理解Android 10 拨打电话流程 packages/apps/Dialer/java/com/android/dialer/dialpadview/DialpadFragment.java 输入完电话号码,点击拨打电话按钮 进入到handleDialButtonPressed中 首先判断是否未空电话号码,如果为空,就会加载上次输入的电话号码 如果不为空,判断电话是否为非法号码,如果非非法号码,逻辑进入下面 首先看CallIntentBuilder 其本质为Intent ,其中

lihuan6656的博客 1537
上一篇: 测试 StringBuffer
下一篇: android电话应用程序概述
mrAking
博客等级 码龄16年 2粉丝 30原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值