Android呼出电话MO流程.docx

上传人:b****7 文档编号:10139369 上传时间:2023-02-08 格式:DOCX 页数:35 大小:207.66KB
下载 相关 举报
Android呼出电话MO流程.docx_第1页
第1页 / 共35页
Android呼出电话MO流程.docx_第2页
第2页 / 共35页
Android呼出电话MO流程.docx_第3页
第3页 / 共35页
Android呼出电话MO流程.docx_第4页
第4页 / 共35页
Android呼出电话MO流程.docx_第5页
第5页 / 共35页
点击查看更多>>
下载资源
资源描述

Android呼出电话MO流程.docx

《Android呼出电话MO流程.docx》由会员分享,可在线阅读,更多相关《Android呼出电话MO流程.docx(35页珍藏版)》请在冰豆网上搜索。

Android呼出电话MO流程.docx

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等重要信

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1