我们从按下拨号开始分析呼出电话的流程。此流程从拨号盘分析到RIL层。
一、应用层的流程
1.1、拨号盘初步处理
@DialpadFragment.java
public void dialButtonPressed() {
//得到号码
final String number = mDigits.getText().toString();
//得到拨号的Intent
final Intent intent = ContactsUtils.getCallIntent(number,
(getActivity() instanceof DialtactsActivity ?
((DialtactsActivity)getActivity()).getCallOrigin() : null));
startActivity(intent);
mClearDigitsOnStop = true;
getActivity().finish();
}
来看上面得到Intent的过程:
@ContactsUtils.java
public static Intent getCallIntent(String number, String callOrigin) {
用号码构建一个类似tel:10086的Uri
return getCallIntent(getCallUri(number), callOrigin);
}
public static Intent getCallIntent(Uri uri, String callOrigin) {
final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (callOrigin != null) {
intent.putExtra(DialtactsActivity.EXTRA_CALL_ORIGIN, callOrigin);
}
return intent;
}
这个过程可以看出,发出的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-alias android:name="PrivilegedOutgoingCallBroadcaster"
android:targetActivity="OutgoingCallBroadcaster"
android:screenOrientation="nosensor"
android:permission="android.permission.CALL_PRIVILEGED">
<intent-filter>
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
</activity-alias>
activity-alias说明这个节点描述的Activity是另一个Activity的别名,也就是说,当前的PrivilegedOutgoingCallBroadcaster是指向OutgoingCallBroadcaster的。
@OutgoingCallBroadcaster.java
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.outgoing_call_broadcaster);
mWaitingSpinner = (ProgressBar) findViewById(R.id.spinner);
Intent intent = getIntent();
processIntent(intent);
}
继续往下看:
private void processIntent(Intent intent) {
final Configuration configuration = getResources().getConfiguration();
String action = intent.getAction();
String number = PhoneNumberUtils.getNumberFromIntent(intent, this);
//得到当前的号码
if (number != null) {
if (!PhoneNumberUtils.isUriNumber(number)) {
number = PhoneNumberUtils.convertKeypadLettersToDigits(number);
number = PhoneNumberUtils.stripSeparators(number);
}
} else {
}
//判断是否是紧急拨号
final boolean isExactEmergencyNumber =
(number != null) && PhoneNumberUtils.isLocalEmergencyNumber(number, this);
final boolean isPotentialEmergencyNumber =
(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;
} else if (Intent.ACTION_CALL_EMERGENCY.equals(action)) {
//紧急呼叫的处理
} else {
}
Uri uri = intent.getData();
String scheme = uri.getScheme();
if (Constants.SCHEME_SIP.equals(scheme) || PhoneNumberUtils.isUriNumber(number)) {
//互联网通话的处理
}
//重新构建Intent
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());
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, new OutgoingCallReceiver(),
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中的内部类,我们直接来看他的接收地方:
public void onReceive(Context context, Intent intent) {
//去掉3妙的定时器
mHandler.removeMessages(EVENT_OUTGOING_CALL_TIMEOUT);
doReceive(context, intent);
finish();
}
public void doReceive(Context context, Intent intent) {
//这里的得到的是false
alreadyCalled = intent.getBooleanE