从源码看拨号流程(一)

1 用户界面

用户打开拨号应用(Dialer)

拨号应用的主界面,通常包含一个DialpadFragment用于显示拨号键盘,以及一个ContactsFragment用于显示联系人列表。

/packages/apps/Dialer/java/com/android/dialer/dialpadview/DialpadFragment.java

DialpadFragment是显示拨号键盘的Fragment。它包含一个数字键盘和一个输入框,用于用户输入电话号码。

/packages/apps/Dialer/java/com/android/dialer/contactsfragment/ContactsFragment.java

ContactsFragment是显示联系人列表的Fragment。

 public void onClick(View view) {
    int resId = view.getId();
    if (resId == R.id.dialpad_floating_action_button) {
      view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
      handleDialButtonPressed();
    } else if (resId == R.id.deleteButton) {
      keyPressed(KeyEvent.KEYCODE_DEL);
    } else if (resId == R.id.digits) {
      if (!isDigitsEmpty()) {
        digits.setCursorVisible(true);
      }
    } else if (resId == R.id.dialpad_overflow) {
      overflowPopupMenu.show();
    } else {
      LogUtil.w("DialpadFragment.onClick", "Unexpected event from: " + view);
    }
  }

根据被点击的ID来执行不同操作:

  • dialpad_floating_action_button:执行触觉反馈performHapticFeedback()并调用handleDialButtonPressed()方法来处理拨号按钮的点击事件。
  • deleteButton:删除按键
  • digits: 数字按钮区域

2 输入处理:

handleDialButtonPressed() 方法
当用户点击拨号按钮时,会调用 handleDialButtonPressed() 方法。这个方法主要做以下几件事:

检查输入的号码是否为空:如果号码为空,则根据当前电话的状态执行特定操作。
检查号码是否被禁止:如果号码符合被禁止的正则表达式模式,则显示错误并清除拨号盘。
拨打号码:如果号码不为空且不被禁止,则使用 PreCall.start() 方法发起通话。

空号码处理:如果号码为空,并且设备是CDMA类型且正在通话中,则发送一个空的Flash信号(用于某些CDMA网络的特殊处理)。否则,显示最后拨打的号码或发出错误提示音。
非空号码处理:如果号码不为空,它会创建一个 CallIntentBuilder 对象,用于构建发起通话的意图,并传递用户输入的号码。然后调用 PreCall.start() 方法来启动通话。
隐藏拨号盘:无论拨打成功与否,都会调用 hideAndClearDialpad() 方法来隐藏拨号盘并清除输入的号码。

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);
        LogUtil.i(
            "DialpadFragment.handleDialButtonPressed",
            "The phone number is prohibited explicitly by a rule.");
        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() 方法用于实际发起通话。它接受一个上下文和一个 CallIntentBuilder 对象,后者用于构建拨打电话的意图,CallIntentBuilder 类用于构建拨打电话的意图。它接受一个电话号码和通话初始化类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值