(O)Telephony分析之通话流程分析(二)拨打电话流程分析(上)

本文详细解析了手机拨号盘界面的拨号流程,涵盖从用户输入号码到通话建立的关键步骤,深入理解Telephony系统的工作机制。
拨打电话,是从通话的拨号盘开始的,而拨号盘的界面是在DialpadFragment,因此,需要从这个地方进行分析

一.拨号盘界面拨号流程

public void onClick(View view) {
    ......
    if (resId == R.id.dialpad_floating_action_button) {
        view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
        // 处理Dial Button点击事件
        handleDialButtonPressed();
    }
    ......
}
通过调用handleDialButtonPressed方法,处理点击拨号按钮后的流程

private void handleDialButtonPressed() {
	// 没有输入号码的情况下,暂不讨论
    if (isDigitsEmpty()) { // No number entered.
        handleDialButtonClickWithEmptyDigits();
    } else {
    	......
      // uri加上tel前缀,并且type设置为INITIATION_DIALPAD,生成URI
      final Intent intent = new CallIntentBuilder(number).setCallInitiationType(LogState.INITIATION_DIALPAD).build();
            // Leo, 尝试去启动一个Activity,如果启动不了,会弹出一个 "Activity is not found" 的Toast框
      DialerUtils.startActivityWithErrorToast(getActivity(), intent);
      // Leo,隐藏拨号盘,并且清除号码盘上的号码
      hideAndClearDialpad(false);  
    }
}
可以看到此处通过初始化CallIntentBuilder,然后调用其build方法,生成一个Intent对象,并作为参数,调用DialerUtils的startActivityWithErrorToast方法
public static class CallIntentBuilder {
    ......
    public CallIntentBuilder(Uri uri) {
        mUri = uri;
    }

    public CallIntentBuilder(String number) {
        this(CallUtil.getCallUri(number));
    }

    public CallIntentBuilder setCallInitiationType(int initiationType) {
        mCallInitiationType = initiationType;
        return this;
    }

    public Intent build() {
    	// Leo, 初始化一个Intent
        return getCallIntent(
                mUri,
                mPhoneAccountHandle,
                mIsVideoCall ? VideoProfile.STATE_BIDIRECTIONAL : VideoProfile.STATE_AUDIO_ONLY,
                mCallInitiationType);
    }
}
从这边来看,首先通过构造方法,将number生成一个Uri,然后通过build方法调用getCallIntent方法,返回一个Intent,而通过上述了解,
知道getCallIntent的参数分别为,
第一个参数为刚刚生成的Uri对象,其是以tel:为前缀的
第二个参数由于并未设置过,因此为null
第三个参数由于没有设置过视频通话,因此为VideoProfile.STATE_AUDIO_ONLY,语音通话
第四个参数为传入的LogState.INITIATION_DIALPAD

public static Intent getCallIntent(
        Uri uri, PhoneAccountHandle accountHandle, int videoState, int callIntiationType) {
	// 初始化一个Intent,action为CALL_ACTION,Data为uri
    final Intent intent = new Intent(CALL_ACTION, uri);
    // 目前应该是没有videoState的,即为VideoProfile.STATE_AUDIO_ONLY
    intent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState);

    final Bundle b = new Bundle();
    // 设置其INITIATION_TYPE,此处第一次为LogState.INITIATION_DIALPAD
    b.putInt(EXTRA_CALL_INITIATION_TYPE, callIntiationType);
    // 设置其Extra
    intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, b);

    // 此前没有设置,应该为null
    
在 Android 系统中,通话流程涉及多个组件的协作,从用户发起拨号请求到通话建立,需要经过多个层次的处理。以下是 Android 系统通话流程的关键分析: ### 通话流程的起点:拨号界面 当用户在拨号应用中输入号码并点击拨号按钮时,会触发 `Intent` 启动电话拨打流程。具体来说,`TelecomUtil.java` 中的 `placeCall` 方法会检查权限,并通过 `getTelecomManager` 调用 `placeCall` 方法,向系统发送拨号请求[^2]。这个过程涉及跨进程通信(IPC),将拨号请求传递给底层服务。 示例代码如下: ```java public static boolean placeCall(Context context, Intent intent) { if (hasCallPhonePermission(context)) { // 第一次跨进程调用 getTelecomManager(context).placeCall(intent.getData(), intent.getExtras()); return true; } return false; } ``` ### 通话流程的中间层:Telecom 管理 `TelecomManager` 是 Android 系统提供的用于管理电话通信的核心类。它负责将上层应用的拨号请求传递给底层的 `Telephony` 框架。在这一阶段,系统会检查当前设备的状态,例如是否处于飞行模式、SIM 卡是否可用等。 ### 通话流程的核心:Telephony 框架 在 `Telephony` 框架中,`GSMPhone` 类是处理 GSM 网络通话的核心类之一。`GSMCallTracker` 则负责跟踪通话的状态,包括拨号、连接、挂断等操作。当用户发起通话时,`GSMCallTracker` 会通过 RIL(Radio Interface Layer)与基带通信,向网络发送拨号请求[^3]。 例如,日志中记录的以下信息显示了通话结束时的调用栈: ``` 01-01 08:02:07.539 D/CallManager( 786): End dial(Handler (com.android.internal.telephony.gsm.GSMPhone) {42522050}, 01058928914) ``` 这表明通话流程的结束阶段涉及 `CallManager` 和 `GSMPhone` 的交互[^1]。 ### 通话流程的最终阶段:通话建立 一旦网络确认通话请求,`GSMCallTracker` 会更新通话状态,并通知上层应用通话已建立。此时,用户可以通过麦克风和扬声器进行通话。 ### 通话流程中的关键类和组件 1. **TelecomUtil.java**:负责处理上层拨号请求并调用系统服务。 2. **TelecomManager**:管理通话的生命周期,包括拨号、接听和挂断。 3. **GSMPhone**:实现 GSM 网络通话的核心类。 4. **GSMCallTracker**:跟踪通话状态并更新 UI。 5. **RIL(Radio Interface Layer)**:负责与基带通信,处理底层网络请求。 ### 通话流程的调试与分析 通过分析系统日志,可以追踪通话流程的各个阶段。例如,日志中记录的 `CallManager` 和 `GSMPhone` 的交互信息有助于定位通话流程中的问题[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值