无论从拨号盘输入号码、通话记录、联系人拨打电话等,都会进入OutgoingCallBroadcaster类中。该类继承Activity,理所当然开始进入onCreate()中,让我们在onCreate()做什么操作:
1、onCreate():
protected void onCreate(Bundle icicle) { super.onCreate(icicle); //获取传入的intent意图 Intent intent = getIntent(); if (icicle != null) { return; } processIntent(intent); }
2、获取到intent后,通过intent获取action和电话号码
private void processIntent(Intent intent) { String action = intent.getAction(); String number = PhoneNumberUtils.getNumberFromIntent(intent, this); //在此对号码进行啦一个转换操作: //比如输入1-800-GOOG-411 实际为1-800-4664-411 if (number != null) { if (!PhoneNumberUtils.isUriNumber(number)) { number = PhoneNumberUtils.convertKeypadLettersToDigits(number); number = PhoneNumberUtils.stripSeparators(number); } } else { Log.w(TAG, "The number obtained from Intent is null."); } }
3、获取到号码后,判断号码是否为紧急号码
final boolean isPotentialEmergencyNumber = (number != null) && PhoneNumberUtils.isPotentialLocalEmergencyNumber(number, this); //在此对紧急号码与非紧急号码设置不同action if (isPotentialEmergencyNumber) { Log.i(TAG, "ACTION_CALL_PRIVILEGED is used while the number is a potential" + " emergency number. Use ACTION_CALL_EMERGENCY as an action instead."); action = Intent.ACTION_CALL_EMERGENCY; } else { action = Intent.ACTION_CALL; } if (DBG) Log.v(TAG, " - updating action from CALL_PRIVILEGED to " + action); intent.setAction(action); } //如果为紧急号码则直接进入InCallScreen界面 if (callNow) { Log.i(TAG, "onCreate(): callNow case! Calling placeCall(): " + intent); PhoneGlobals.getInstance().callController.placeCall(intent); }
4、如果不是紧急号码,则通过另一种方式开启InCallScreen():
//发送广播
Intent broadcastIntent = new Intent(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()); // Need to raise foreground in-call UI as soon as possible while allowing 3rd party app // to intercept the outgoing call. broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); if (DBG) Log.v(TAG, " - Broadcasting intent: " + broadcastIntent + "."); // Set a timer so that we can prepare for unexpected delay introduced by the broadcast. // If it takes too much time, the timer will show "waiting" spinner. // This message will be removed when OutgoingCallReceiver#onReceive() is called before the // timeout. mHandler.sendEmptyMessageDelayed(EVENT_OUTGOING_CALL_TIMEOUT, OUTGOING_CALL_TIMEOUT_THRESHOLD); sendOrderedBroadcastAsUser(broadcastIntent, UserHandle.OWNER, PERMISSION, new OutgoingCallReceiver(), null, // scheduler Activity.RESULT_OK, // initialCode number, // initialData: initial value for the result data null); // initialExtras //接收广播,执行onReceive(): alreadyCalled = intent.getBooleanExtra( OutgoingCallBroadcaster.EXTRA_ALREADY_CALLED, false); //如果已经存在InCallScreen,直接finish if (alreadyCalled) { if (DBG) Log.v(TAG, "CALL already placed -- returning."); return; } //获取到number和uri String number = getResultData(); String originalUri = intent.getStringExtra( OutgoingCallBroadcaster.EXTRA_ORIGINAL_URI); //开启sip网络通话,在2.2版本好像是直接开启InCallScreen startSipCallOptionHandler(context, intent, uri, number);
5、通过代码可知,OutgoingCallBroadcaster只做了对number及uri数据传递和紧急号码判断。既然每个去电都必须通过此类,我们可以通过它对同时拨打号码数量的限制。google只允许同时拨打2个电话,大家可以试试,我们先看看google是如何限制的:
CallManager (frameworks)----- canDial():通过修改此类限制----比如三方通话,同时我们也可以在OutgoingCallBroadcaster中onCreate()中拦截。
//判断是否可以拨打 private boolean canDial(Phone phone) { int serviceState = phone.getServiceState().getState(); boolean hasRingingCall = hasActiveRingingCall();//是否响铃 boolean hasActiveCall = hasActiveFgCall();//是否活动在前台 boolean hasHoldingCall = hasActiveBgCall();//是否后台 boolean allLinesTaken = hasActiveCall && hasHoldingCall;
Call.State fgCallState = getActiveFgCallState();
boolean result = (serviceState != ServiceState.STATE_POWER_OFF && !hasRingingCall && !allLinesTaken && ((fgCallState == Call.State.ACTIVE) || (fgCallState == Call.State.IDLE) || (fgCallState == Call.State.DISCONNECTED))); return result; }