Android呼出电话MO流程.docx
- 文档编号:3529094
- 上传时间:2023-05-06
- 格式:DOCX
- 页数:35
- 大小:207.66KB
Android呼出电话MO流程.docx
《Android呼出电话MO流程.docx》由会员分享,可在线阅读,更多相关《Android呼出电话MO流程.docx(35页珍藏版)》请在冰点文库上搜索。
Android呼出电话MO流程
Android呼出电话MO流程
目录(?
)[-]
∙一应用层的流程
1拨号盘初步处理
1号码初级处理阶段
1互联网通话处理阶段SipCallOptionHandlerjava
1Phone模块其他的处理
∙二framework中的流程
1Phone的来历
1我们是如何通过pickPhoneBasedOnNumber的方式得到的Phone对象的
1继续拨号之旅
∙三总体流程图
我们从按下拨号开始分析呼出电话的流程。
此流程从拨号盘分析到RIL层。
一、应用层的流程
1.1、拨号盘初步处理
[java]viewplaincopy
∙@DialpadFragment.java
∙publicvoiddialButtonPressed(){
∙//得到号码
∙finalStringnumber=mDigits.getText().toString();
∙//得到拨号的Intent
∙finalIntentintent=ContactsUtils.getCallIntent(number,
∙(getActivity()instanceofDialtactsActivity?
∙((DialtactsActivity)getActivity()).getCallOrigin():
null));
∙startActivity(intent);
∙mClearDigitsOnStop=true;
∙getActivity().finish();
∙}
来看上面得到Intent的过程:
[java]viewplaincopy
∙@ContactsUtils.java
∙publicstaticIntentgetCallIntent(Stringnumber,StringcallOrigin){
∙用号码构建一个类似tel:
10086的Uri
∙returngetCallIntent(getCallUri(number),callOrigin);
∙}
∙publicstaticIntentgetCallIntent(Uriuri,StringcallOrigin){
∙finalIntentintent=newIntent(Intent.ACTION_CALL_PRIVILEGED,uri);
∙intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
∙if(callOrigin!
=null){
∙intent.putExtra(DialtactsActivity.EXTRA_CALL_ORIGIN,callOrigin);
∙}
∙returnintent;
∙}
这个过程可以看出,发出的Intent由一下几个结构组成:
1、Action为:
ACTION_CALL_PRIVILEGED,(android.intent.action.CALL_PRIVILEGED);
2、Flag为:
FLAG_ACTIVITY_NEW_TASK;
3、号码Uri为:
tel:
10086
然后经过startActivity发送出去。
那么是那个Activity接受的呢?
1.2、号码初级处理阶段
这个过程主要针对紧急呼叫处理(OutgoingCallBroadcaster.java)。
在Phone模块的AndroidManifest.xml文件中有如下描述:
[java]viewplaincopy
∙ name="PrivilegedOutgoingCallBroadcaster" ∙android: targetActivity="OutgoingCallBroadcaster" ∙android: screenOrientation="nosensor" ∙android: permission="android.permission.CALL_PRIVILEGED"> ∙ ∙ name="android.intent.action.CALL_PRIVILEGED"/> ∙ name="android.intent.category.DEFAULT"/> ∙ scheme="tel"/> ∙ ∙ activity-alias说明这个节点描述的Activity是另一个Activity的别名,也就是说,当前的PrivilegedOutgoingCallBroadcaster是指向OutgoingCallBroadcaster的。 [java]viewplaincopy ∙@OutgoingCallBroadcaster.java ∙protectedvoidonCreate(Bundleicicle){ ∙super.onCreate(icicle); ∙setContentView(R.layout.outgoing_call_broadcaster); ∙mWaitingSpinner=(ProgressBar)findViewById(R.id.spinner); ∙ ∙Intentintent=getIntent(); ∙processIntent(intent); ∙} 继续往下看: [java]viewplaincopy ∙privatevoidprocessIntent(Intentintent){ ∙finalConfigurationconfiguration=getResources().getConfiguration(); ∙ ∙Stringaction=intent.getAction(); ∙Stringnumber=PhoneNumberUtils.getNumberFromIntent(intent,this); ∙ ∙//得到当前的号码 ∙if(number! =null){ ∙if(! PhoneNumberUtils.isUriNumber(number)){ ∙number=PhoneNumberUtils.convertKeypadLettersToDigits(number); ∙number=PhoneNumberUtils.stripSeparators(number); ∙} ∙}else{ ∙} ∙ ∙//判断是否是紧急拨号 ∙finalbooleanisExactEmergencyNumber= ∙(number! =null)&&PhoneNumberUtils.isLocalEmergencyNumber(number,this); ∙finalbooleanisPotentialEmergencyNumber= ∙(number! =null)&&PhoneNumberUtils.isPotentialLocalEmergencyNumber(number,this); ∙ ∙if(Intent.ACTION_CALL_PRIVILEGED.equals(action)){ ∙if(isPotentialEmergencyNumber){ ∙//紧急拨号的action ∙action=Intent.ACTION_CALL_EMERGENCY; ∙}else{ ∙//非紧急拨号的action ∙action=Intent.ACTION_CALL; ∙} ∙//重新设置Action,当前不是紧急呼叫,因此Action改为ACTION_CALL ∙intent.setAction(action); ∙} ∙ ∙if(Intent.ACTION_CALL.equals(action)){ ∙if(isPotentialEmergencyNumber){ ∙//判断不成立 ∙} ∙//当前的callNow为false ∙callNow=false; ∙}elseif(Intent.ACTION_CALL_EMERGENCY.equals(action)){ ∙//紧急呼叫的处理 ∙}else{ ∙} ∙ ∙Uriuri=intent.getData(); ∙Stringscheme=uri.getScheme(); ∙if(Constants.SCHEME_SIP.equals(scheme)||PhoneNumberUtils.isUriNumber(number)){ ∙//互联网通话的处理 ∙} ∙ ∙//重新构建Intent ∙IntentbroadcastIntent=newIntent(Intent.ACTION_NEW_OUTGOING_CALL); ∙if(number! =null){ ∙broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER,number); ∙} ∙PhoneUtils.checkAndCopyPhoneProviderExtras(intent,broadcastIntent); ∙broadcastIntent.putExtra(EXTRA_ALREADY_CALLED,callNow); ∙broadcastIntent.putExtra(EXTRA_ORIGINAL_URI,uri.toString()); ∙broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); ∙ ∙//添加一个2秒的定时器,2秒内Intent没有收到的话,就显示一个进度条 ∙mHandler.sendEmptyMessageDelayed(EVENT_OUTGOING_CALL_TIMEOUT, ∙OUTGOING_CALL_TIMEOUT_THRESHOLD); ∙ ∙//发送广播,而且指明了接收者是OutgoingCallReceiver ∙sendOrderedBroadcastAsUser(broadcastIntent,UserHandle.OWNER, ∙PERMISSION,newOutgoingCallReceiver(), ∙null, ∙Activity.RESULT_OK, ∙number, ∙null); ∙} 这个过程其实就是对原始的Intent进行解析,对是否紧急呼叫进行不同的处理,对于正常的呼叫,需要重新构建Intent并发送出去。 新的Intent构成: Intent: ACTION_NEW_OUTGOING_CALL; EXTRA_ALREADY_CALLED: false; EXTRA_ORIGINAL_URI: 号码的Uri; 发送目标: OutgoingCallReceiver; 这里所谓的目标OutgoingCallReceiver其实就是OutgoingCallBroadcaster.java中的内部类,我们直接来看他的接收地方: [java]viewplaincopy ∙publicvoidonReceive(Contextcontext,Intentintent){ ∙//去掉3妙的定时器 ∙mHandler.removeMessages(EVENT_OUTGOING_CALL_TIMEOUT); ∙doReceive(context,intent); ∙finish(); ∙} ∙publicvoiddoReceive(Contextcontext,Intentintent){ ∙//这里的得到的是false ∙alreadyCalled=intent.getBooleanExtra(OutgoingCallBroadcaster.EXTRA_ALREADY_CALLED,false); ∙if(alreadyCalled){ ∙return; ∙} ∙ ∙//得到号码 ∙number=getResultData(); ∙ ∙finalPhoneGlobalsapp=PhoneGlobals.getInstance(); ∙//OTASP功能,CDMA制式支持 ∙if(TelephonyCapabilities.supportsOtasp(app.phone)){ ∙} ∙ ∙//得到号码的Uri ∙originalUri=intent.getStringExtra(OutgoingCallBroadcaster.EXTRA_ORIGINAL_URI); ∙Uriuri=Uri.parse(originalUri); ∙ ∙//把字母转换为数字,比如: a-->2;d-->3;g-->4等 ∙number=PhoneNumberUtils.convertKeypadLettersToDigits(number); ∙//把所有字符转换为数字 ∙number=PhoneNumberUtils.stripSeparators(number); ∙ ∙//继续处理 ∙startSipCallOptionHandler(context,intent,uri,number); ∙} ∙privatevoidstartSipCallOptionHandler(Contextcontext,Intentintent,Uriuri,Stringnumber){ ∙//再次构建Intent ∙IntentnewIntent=newIntent(Intent.ACTION_CALL,uri); ∙newIntent.putExtra(EXTRA_ACTUAL_NUMBER_TO_DIAL,number); ∙//把原始的Intent数据拷贝过来 ∙//主要去解析EXTRA_GATEWAY_PROVIDER_PACKAGE和EXTRA_GATEWAY_URI,而这两项均为null ∙PhoneUtils.checkAndCopyPhoneProviderExtras(intent,newIntent); ∙ ∙//还有一个Intent ∙IntentselectPhoneIntent=newIntent(ACTION_SIP_SELECT_PHONE,uri); ∙//指明接受者是SipCallOptionHandler ∙selectPhoneIntent.setClass(context,SipCallOptionHandler.class); ∙//把上面的Intent放到EXTRA_NEW_CALL_INTENT中 ∙selectPhoneIntent.putExtra(EXTRA_NEW_CALL_INTENT,newIntent); ∙//用新的task装载 ∙selectPhoneIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ∙//发送,走起 ∙context.startActivity(selectPhoneIntent); ∙} 上面的操作又是发起了一个Intent,构成有: Action--->ACTION_SIP_SELECT_PHONE EXTRA_NEW_CALL_INTENT--->拨号的Intent,而且这个Intent的Action为ACTION_CALL EXTRA_ACTUAL_NUMBER_TO_DIAL--->为拨号的号码 1.3、互联网通话处理阶段(SipCallOptionHandler.java) 我们来看上面Intent的接受过程,在SipCallOptionHandler中: [java]viewplaincopy ∙@SipCallOptionHandler.java ∙publicvoidonCreate(BundlesavedInstanceState){ ∙super.onCreate(savedInstanceState); ∙ ∙//得到Intent ∙Intentintent=getIntent(); ∙Stringaction=intent.getAction(); ∙ ∙//外层的Intent ∙if(! OutgoingCallBroadcaster.ACTION_SIP_SELECT_PHONE.equals(action)){ ∙finish(); ∙return; ∙} ∙ ∙//得到拨号的Intent ∙mIntent=(Intent)intent.getParcelableExtra(OutgoingCallBroadcaster.EXTRA_NEW_CALL_INTENT); ∙if(mIntent==null){ ∙finish(); ∙return; ∙} ∙ ∙//是否支持互联网通话 ∙booleanvoipSupported=PhoneUtils.isVoipSupported(); ∙mSipProfileDb=newSipProfileDb(this); ∙mSipSharedPreferences=newSipSharedPreferences(this); ∙mCallOption=mSipSharedPreferences.getSipCallOption(); ∙Uriuri=mIntent.getData(); ∙Stringscheme=uri.getScheme(); ∙//得到通话的号码 ∙mNumber=PhoneNumberUtils.getNumberFromIntent(mIntent,this); ∙//是否有网络 ∙booleanisInCellNetwork=PhoneGlobals.getInstance().phoneMgr.isRadioOn(); ∙//是否是tel: 或者sip: 的协议 ∙booleanisKnownCallScheme=Constants.SCHEME_TEL.equals(scheme)||Constants.SCHEME_SIP.equals(scheme); ∙booleanisRegularCall=Constants.SCHEME_TEL.equals(scheme) ∙&&! PhoneNumberUtils.isUriNumber(mNumber); ∙ ∙if(! isKnownCallScheme){ ∙//异常处理,处理非法协议。 ∙setResultAndFinish(); ∙return; ∙} ∙ ∙if(! voipSupported){ ∙if(! isRegularCall){ ∙showDialog(DIALOG_NO_VOIP); ∙}else{ ∙//当前不是IP通话,因此走这里 ∙setResultAndFinish(); ∙} ∙return; ∙} ∙ ∙setResultAndFinish(); ∙} 继续看setResultAndFinish [java]viewplaincopy ∙privatevoidsetResultAndFinish(){ ∙//放在主线程中操作 ∙runOnUiThread(newRunnable(){ ∙publicvoidrun(){ ∙if(mOutgoingSipProfile! =null){ ∙//互联网通话 ∙if(! isNetworkConnected()){ ∙showDialog(DIALOG_NO_INTERNET_ERROR); ∙return; ∙} ∙createSipPhoneIfNeeded(mOutgoingSipProfile); ∙mIntent.putExtra(OutgoingCallBroadcaster.EXTRA_SIP_PHONE_URI, ∙mOutgoingSipProfile.getUriString()); ∙if(mMakePrimary){ ∙mSipSharedPreferences.setPrimaryAccount( ∙mOutgoingSipProfile.getUriString()); ∙} ∙} ∙ ∙if(mUseSipPhone&&mOutgoingSipProfile==null){ ∙showDialog(DIALOG_START_SIP_SETTINGS); ∙return; ∙}else{ ∙//正常拨号 ∙PhoneGlobals.getInstance().callController.placeCall(mIntent); ∙} ∙finish(); ∙} ∙}); ∙} 上面可以看出,在SipCallOptionHandler.java文件中主要针对互联网通话进行处理,注意,这里的互联网通话和IP拨号不同。 1.4、Phone模块其他的处理 主要作用是把intent解析为号码,同时得到拨号必须的Phone、CM、context等重要信
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 呼出 电话 MO 流程