(学习笔记)android 5.0 系统去电流程状态判断(下)

本文详细分析了Android 5.0系统中去电流程的异常状态处理机制,包括网络状态和飞行模式的判断。在紧急号码拨打、无网络、飞行模式等场景下,系统如何进行判断并给出相应提示。文章通过流程图和步骤解释了从应用层到框架层的通信过程,以及异常情况下的连接创建和失败处理。最后,总结了状态判断的关键点,强调了在特定网络环境下对提示信息的处理方法。
摘要由CSDN通过智能技术生成

需求:

判断系统拨号的每个状态,根据状态不同弹窗提示。

需求分析:

1、无卡开机要求提示用户:Emergency calls only. Please enter Emergency Number;
2、无网络覆盖情况,当户用拨打所有号码,界面上立即给出提示“No network coverage!";
3、飞行模式打开的情况下,用户拨打紧急号码时,弹出提示,提示用户要先关闭飞行模式;
4、当两张卡都处于有限服务状态的时候 拨打号码, 手机提示"Emergency call only, Please enter an Emergency number!"

目的:

通过需求了解去电的基本流程。

附上本次要分析的流程图,正常情况下就不分析了,为了满足需求,主要分析的是去电情况下的异常状态的处理机制。

这里写图片描述

上一篇笔记分析到了这个流程图的第一步,在这个方法中Telecom模块绑定了InCallUI这个进程,可以通过mInCallServices对通话界面的状态进行各种控制。这篇笔记接着这个方法开始分析。

第1步:
static void processOutgoingCallIntent(Context context, Intent intent) {

        ...
        //首次绑定InCallUI进程。
        CallsManager.getInstance().getInCallController().bind();
        /// @}

       ...
        //返回一个CALL对象,同时,startOutgoingCall()首次对InCallUI进行控制
        Call call = getCallsManager().startOutgoingCall(handle, phoneAccountHandle, clientExtras);
       ...

            NewOutgoingCallIntentBroadcaster broadcaster = new NewOutgoingCallIntentBroadcaster(
                    context, getCallsManager(), call, intent, isDefaultDialer);
        //进入拨号流程
            final int result = broadcaster.processIntent();
            final boolean success = result == DisconnectCause.NOT_DISCONNECTED;

            if (!success && call != null) {
                disconnectCallAndShowErrorDialog(context, call, result);
            }
        }
    }
第2、3步:
int processIntent() {

       ...

        final boolean isPotentialEmergencyNumber = isPotentialEmergencyNumber(number);

    //仅对系统拨号器情况下进行判断;
    //紧急号码情况下,将Aciton 重写为 action = Intent.ACTION_CALL_EMERGENCY;
    //非紧急号码情况下,将Aciton 重写为 action = Intent.ACTION_CALL;
    //此时,第三方软件的Aciton一直是Intent.ACTION_CALL;
        rewriteCallIntentAction(intent, isPotentialEmergencyNumber);
        action = intent.getAction();
        // True for certain types of numbers that are not intended to be intercepted or modified
        // by third parties (e.g. emergency numbers).
        boolean callImmediately = false;

    //如果是紧急号码,系统拨号Action不会是 Intent.ACTION_CALL,可以判定第三方拨打的紧急号码
        if (Intent.ACTION_CALL.equals(action)) {
            if (isPotentialEmergencyNumber) {
                if (!mIsDefaultOrSystemPhoneApp) {
                    Log.w(this, "Cannot call potential emergency number %s with CALL Intent %s "
                            + "unless caller is system or default dialer.", number, intent);
                    launchSystemDialer(intent.getData());
                    return DisconnectCause.OUTGOING_CANCELED;
                } else {
                    callImmediately = true;
                }
            }
        } else if (Intent.ACTION_CALL_EMERGENCY.equals(action)) { //系统拨打的紧急号码
            ...
            callImmediately = true;
        } else {
            Log.w(this, "Unhandled Intent %s. Ignoring and not placing call.", intent);
            return DisconnectCause.INVALID_NUMBER;
        }

        if (callImmediately) {
            Log.i(this, "Placing call immediately instead of waiting for "
                    + " OutgoingCallBroadcastReceiver: %s", intent);
            String scheme = isUriNumber ? PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL;
            boolean speakerphoneOn = mIntent.getBooleanExtra(
                    TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, false);
            int videoState = mIntent.getIntExtra(
                    TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
                    VideoProfile.VideoState.AUDIO_ONLY);
            mCallsManager.placeOutgoingCall(mCall, Uri.fromParts(scheme, number, null), null,
                    speakerphoneOn, videoState);

            // Don't return but instead continue and send the ACTION_NEW_OUTGOING_CALL broadcast
            // so that third parties can still inspect (but not intercept) the outgoing call. When
            // the broadcast finally reaches the OutgoingCallBroadcastReceiver, we'll know not to
            // initiate the call again because of the presence of the EXTRA_ALREADY_CALLED extra.
        }
    //紧急号码情况在这个方法下会被屏蔽,上面已经处理过
        broadcastIntent(intent, number, !callImmediately);
        return DisconnectCause.NOT_DISCONNECTED;
    }

这一步对号码以及Action做了区分,根据具体情况重写了Aciton ;

  1. 系统拨打紧急号码会立即进入拨号流程;
  2. 第三方拨打紧急号码会立即跳转至系统拨号盘;
  3. 其他情况发送广播执行拨号流程。
第4步:
 void placeOutgoingCall(Call call, Uri handle, GatewayInfo gatewayInfo, boolean speakerphoneOn,
            int videoState) {
       ...

        boolean isEmergencyCall = TelephonyUtil.shouldProcessAsEmergency(mContext,
                call.getHandle());
        Log.i(this, "placeOutgoingCall isEmergencyCall = " + isEmergencyCall);
       ...
    //如果是无卡状态,在这里就不会继续往下走了,上一篇判断的无卡状态,从log上看,走到这里就停止了。
        if (call.getTargetPhoneAccount() != null || isEmergencyCall) {
            // If the account has been set, proceed to place the outgoing call.
            // Otherwise the connection will be initiated when the account is set by the user.
            /// M: call control start. @{
            // If already have an active call, need to hold active call first.
            Call activeCall = getFirstCallWithState(CallState.ACTIVE);
            if (activeCall == null 
                    || isPotentialMMICode(call.getHandle())
                    || isPotentialInCallMMICode(call.getHandle())) {
                Log.i(this, "Active call is null, start outgoing call %s.", call);
                call.startCreateConnection(mPhoneAccountRegistrar);
            } else if (activeCall.can(PhoneCapabilities.HOLD)) {
                Log.i(this, "Holding active call %s before start outgoing call %s.",
                        activeCall, call);
                mPendingCallActions.put(activeCall, new PendingCallAction(call,
                        PendingCallAction.PENDING_ACTION_OUTGOING,
                        VideoProfile.VideoState.AUDIO_ONLY));
                activeCall.hold();
            } else if (isEmergencyCall) {
                mPendingCallActions.put(activeCall, new PendingCallAction(call,
                        PendingCallAction.PENDING_ACTION_OUTGOING,
                    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值