1.主界面
打开dialer界面,抓取log:,主界面为com.android.dialer/.main.impl.MainActivity
查看MainActivity,主要逻辑如下
protected void onCreate(Bundle savedInstanceState) {
。。。
activePeer = getNewPeer();
activePeer.onActivityCreate(savedInstanceState);
showBlockReportSpamDialogReceiver =
new ShowBlockReportSpamDialogReceiver(getSupportFragmentManager());
}
protected MainActivityPeer getNewPeer() {
if (CallLogConfigComponent.get(this).callLogConfig().isNewPeerEnabled()) { //CallLogConfigImpl.java
return new NewMainActivityPeer(this);
} else {
return new OldMainActivityPeer(this); //默认走的这
}
}
public boolean isNewPeerEnabled() { //判断条件
return sharedPreferences.getBoolean(NEW_PEER_ENABLED_PREF_KEY, false);
}
查看OldMainActivityPeer
public void onActivityCreate(Bundle savedInstanceState) {
LogUtil.enterBlock("OldMainActivityPeer.onActivityCreate");
setTheme();
activity.setContentView(R.layout.main_activity);//布局文件
initUiListeners();
initLayout(savedInstanceState);
SmartDialPrefix.initializeNanpSettings(activity);
}
布局分析
//main_activity.xml
<include
android:id="@+id/toolbar"
layout="@layout/toolbar_layout"/> //最上边的一栏
<FrameLayout
android:id="@+id/fragment_container" //中间显示
/>
<com.android.dialer.widget.DialerFloatingActionButton //底部按钮
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_gravity="end|bottom"
android:src="@drawable/quantum_ic_dialpad_white_24"
android:contentDescription="@string/dialpad_button_content_description"
app:backgroundTint="?android:attr/colorAccent"/>
<include
android:id="@+id/bottom_nav_bar" //最下边的一栏
layout="@layout/bottom_nav_bar_layout"/>
//toolbar_layout.xml
<TextView
android:id="@+id/search_box_start_search" //搜索栏
/>
<ImageButton
android:id="@+id/main_options_menu_button"//菜单
/>
2.拨号界面DialpadFragment
在OldMainActivityPeer中点击拨号按钮会执行以下代码
fab.setOnClickListener(
v -> {
searchController.showDialpad(true);
});
private void showDialpad(boolean animate, boolean fromNewIntent) {
dialpadFragment = new DialpadFragment();
dialpadFragment.setStartedFromNewIntent(fromNewIntent); //显示DialpadFragment
transaction.commit();
}
log打印
在DialpadFragment点击拨号会执行以下逻辑,重点关注prohibitedPhoneNumberRegexp,设置该值可以限制输入哪些号码,其定义在strings.xml中的config_prohibited_phone_number_regexp
public void onClick(View view) {
int resId = view.getId();
if (resId == R.id.dialpad_floating_action_button) {
view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
handleDialButtonPressed(); //执行这
}
。。。
}
private void handleDialButtonPressed() {
if (isDigitsEmpty()) { // No number entered.
// No real call made, so treat it as a click
PerformanceReport.recordClick(UiAction.Type.PRESS_CALL_BUTTON_WITHOUT_CALLING);
handleDialButtonClickWithEmptyDigits();
} else {
final String number = digits.getText().toString();
// "persist.radio.otaspdial" is a temporary hack needed for one carrier's automated
// test equipment.
// TODO: clean it up.
if (number != null
&& !TextUtils.isEmpty(prohibitedPhoneNumberRegexp)
&& number.matches(prohibitedPhoneNumberRegexp)) { //输入的数字符合
PerformanceReport.recordClick(UiAction.Type.PRESS_CALL_BUTTON_WITHOUT_CALLING);
if (getActivity() != null) {
DialogFragment dialogFragment =
ErrorDialogFragment.newInstance(R.string.dialog_phone_call_prohibited_message);
dialogFragment.show(getFragmentManager(), "phone_prohibited_dialog");
}
// Clear the digits just in case.
clearDialpad();
} else {
PreCall.start(getContext(), new CallIntentBuilder(number, CallInitiationType.Type.DIALPAD));//没有限制时执行这
hideAndClearDialpad();
}
}
}
后续逻辑为
PreCall.start
→DialerUtils.startActivityWithErrorToast
→startActivityWithErrorToast
→placeCallOrMakeToast
–>TelecomUtil.placeCall(context, intent);
–>getTelecomManager(context).placeCall(intent.getData(), intent.getExtras());