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