Android呼出电话MO流程Word文档格式.docx
《Android呼出电话MO流程Word文档格式.docx》由会员分享,可在线阅读,更多相关《Android呼出电话MO流程Word文档格式.docx(35页珍藏版)》请在冰点文库上搜索。
![Android呼出电话MO流程Word文档格式.docx](https://file1.bingdoc.com/fileroot1/2023-5/5/45365123-ea8a-4c3f-a2da-83eca237c57c/45365123-ea8a-4c3f-a2da-83eca237c57c1.gif)
∙((DialtactsActivity)getActivity()).getCallOrigin():
null));
∙startActivity(intent);
∙mClearDigitsOnStop=true;
∙getActivity().finish();
∙}
来看上面得到Intent的过程:
∙@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文件中有如下描述:
∙<
activity-aliasandroid:
name="
PrivilegedOutgoingCallBroadcaster"
∙android:
targetActivity="
OutgoingCallBroadcaster"
screenOrientation="
nosensor"
permission="
android.permission.CALL_PRIVILEGED"
>
intent-filter>
actionandroid:
android.intent.action.CALL_PRIVILEGED"
/>
categoryandroid:
android.intent.category.DEFAULT"
dataandroid:
scheme="
tel"
/intent-filter>
/activity-alias>
activity-alias说明这个节点描述的Activity是另一个Activity的别名,也就是说,当前的PrivilegedOutgoingCallBroadcaster是指向OutgoingCallBroadcaster的。
∙@OutgoingCallBroadcaster.java
∙protectedvoidonCreate(Bundleicicle){
∙super.onCreate(icicle);
∙setContentView(R.layout.outgoing_call_broadcaster);
∙mWaitingSpinner=(ProgressBar)findViewById(R.id.spinner);
∙
∙Intentintent=getIntent();
∙processIntent(intent);
继续往下看:
∙privatevoidprocessIntent(Intentintent){
∙finalConfigurationconfiguration=getResources().getConfiguration();
∙Stringaction=intent.getAction();
∙Stringnumber=PhoneNumberUtils.getNumberFromIntent(intent,this);
∙//得到当前的号码
∙if(number!
∙if(!
PhoneNumberUtils.isUriNumber(number)){
∙number=PhoneNumberUtils.convertKeypadLettersToDigits(number);
∙number=PhoneNumberUtils.stripSeparators(number);
∙}else{
∙//判断是否是紧急拨号
∙finalbooleanisExactEmergencyNumber=
∙(number!
=null)&
&
PhoneNumberUtils.isLocalEmergencyNumber(number,this);
∙finalbooleanisPotentialEmergencyNumber=
PhoneNumberUtils.isPotentialLocalEmergencyNumber(number,this);
∙if(Intent.ACTION_CALL_PRIVILEGED.equals(action)){
∙if(isPotentialEmergencyNumber){
∙//紧急拨号的action
∙action=Intent.ACTION_CALL_EMERGENCY;
∙//非紧急拨号的action
∙action=Intent.ACTION_CALL;
∙//重新设置Action,当前不是紧急呼叫,因此Action改为ACTION_CALL
∙intent.setAction(action);
∙if(Intent.ACTION_CALL.equals(action)){
∙//判断不成立
∙//当前的callNow为false
∙callNow=false;
∙}elseif(Intent.ACTION_CALL_EMERGENCY.equals(action)){
∙//紧急呼叫的处理
∙Uriuri=intent.getData();
∙Stringscheme=uri.getScheme();
∙if(Constants.SCHEME_SIP.equals(scheme)||PhoneNumberUtils.isUriNumber(number)){
∙//互联网通话的处理
∙//重新构建Intent
∙IntentbroadcastIntent=newIntent(Intent.ACTION_NEW_OUTGOING_CALL);
∙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中的内部类,我们直接来看他的接收地方:
∙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等
∙//把所有字符转换为数字
∙//继续处理
∙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中:
∙@SipCallOptionHandler.java
∙publicvoidonCreate(BundlesavedInstanceState){
∙super.onCreate(savedInstanceState);
∙//得到Intent
∙//外层的Intent
OutgoingCallBroadcaster.ACTION_SIP_SELECT_PHONE.equals(action)){
∙mIntent=(Intent)intent.getParcelableExtra(OutgoingCallBroadcaster.EXTRA_NEW_CALL_INTENT);
∙if(mIntent==null){
∙//是否支持互联网通话
∙booleanvoipSupported=PhoneUtils.isVoipSupported();
∙mSipProfileDb=newSipProfileDb(this);
∙mSipSharedPreferences=newSipSharedPreferences(this);
∙mCallOption=mSipSharedPreferences.getSipCallOption();
∙Uriuri=mIntent.getData();
∙//得到通话的号码
∙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);
isKnownCallScheme){
∙//异常处理,处理非法协议。
∙setResultAndFinish();
voipSupported){
isRegularCall){
∙showDialog(DIALOG_NO_VOIP);
∙//当前不是IP通话,因此走这里
继续看setResultAndFinish
∙privatevoidsetResultAndFinish(){
∙//放在主线程中操作
∙runOnUiThread(newRunnable(){
∙publicvoidrun(){
∙if(mOutgoingSipProfile!
∙//互联网通话
isNetworkConnected()){
∙showDialog(DIALOG_NO_INTERNET_ERROR);
∙createSipPhoneIfNeeded(mOutgoingSipProfile);
∙mIntent.putExtra(OutgoingCallBroadcaster.EXTRA_SIP_PHONE_URI,
∙mOutgoingSipProfile.getUriString());
∙if(mMakePrimary){
∙mSipSharedPreferences.setPrimaryAccount(
∙if(mUseSipPhone&
mOutgoingSipProfile==null){
∙showDialog(DIALOG_START_SIP_SETTINGS);
∙//正常拨号
∙PhoneGlobals.getInstance().callController.placeCall(mIntent);
∙});
上面可以看出,在SipCallOptionHandler.java文件中主要针对互联网通话进行处理,注意,这里的互联网通话和IP拨号不同。
1.4、Phone模块其他的处理
主要作用是把intent解析为号码,同时得到拨号必须的Phone、CM、context等重要信