admin管理员组

文章数量:1577830

outgoing call 有三类, 分别用三种intent 去标记 三种intent 定义如下

     * This method will handle three kinds of actions:
     *
     * - CALL (action for usual outgoing voice calls)
     * - CALL_PRIVILEGED (can come from built-in apps like contacts / voice dialer / bluetooth)
     * - CALL_EMERGENCY (from the EmergencyDialer that's reachable from the lockscreen.)

紧急电话的几种调用方式

  拨打Emergency call 是不需要卡的。应该走的是一种特殊的链路。

  Emergency call 被两种Intent所触发(Intent.ACTION_CALL_EMERGENCY 和 Intent.ACTION_CALL_PRIVILEGED).
  CALL_PRIVILEGED是被系统级的应用所发起的,而CALL_EMERGENCY Intent 是从紧急呼叫的拨号盘里发起的,就是手机在没有SIM卡的模式下显示的拨号盘。CALL_PRIVILEGED这个intent 接到后会检查号码是否是emergency number, 如果是紧急电话的号码就会把intent的action 替换为ACTION_CALL_EMERGENCY, 如果不是就替换成ACTION_CALL。由此可看,虽然我们有三种call的intent action, 但是我们实际有效果的就是上述两种。CALL_PRIVILEGED这种action的call的作用的是能把紧急电话的号码带给phone app去处理,而普通的call action的intent是不可以的。
processIntent实现里用一个flag变量callNow来控制是否拨打电话, callNow在满足拨打emengency call的时候被置为true,正常call会被在startSipCallOptionHandler 这里到类SipCallOptionHandler去处理。
  3rd App是没有权限拨打Emergency call的, 如果3rd App在发起一个Intent.ACTION_CALL里带有Emergency number,会被阻止.OutgoingCallBroadcaster 类里的processIntent函数承担这部分的主要工作。
  下面是google的代码

526        if (Intent.ACTION_CALL.equals(action)) {
527            if (isPotentialEmergencyNumber) {
528                Log.w(TAG, "Cannot call potential emergency number '" + number
529                        + "' with CALL Intent " + intent + ".");
530                Log.i(TAG, "Launching default dialer instead...");
531
532                Intent invokeFrameworkDialer = new Intent();
533
534                // TwelveKeyDialer is in a tab so we really want
535                // DialtactsActivity.  Build the intent 'manually' to
536                // use the java resolver to find the dialer class (as
537                // opposed to a Context which look up known android
538                // packages only)
539                final Resources resources = getResources();
540                invokeFrameworkDialer.setClassName(
541                        resources.getString(R.string.ui_default_package),
542                        resources.getString(R.string.dialer_default_class));
543                invokeFrameworkDialer.setAction(Intent.ACTION_DIAL);
544                invokeFrameworkDialer.setData(intent.getData());
545                if (DBG) Log.v(TAG, "onCreate(): calling startActivity for Dialer: "
546                               + invokeFrameworkDialer);
547                startActivity(invokeFrameworkDialer);
548                finish();
549                return;
550            }
551            callNow = false;

拨打紧急电话与modem的互动关系

   我们所注意到的是在拨打紧急电话的时候,当我们发现是一个紧急电话并且modem 在power off的模式下,会开启一个消息队列去开启modem startEmergencyCallFromAirplaneModeSequence这里面会有个timeout 的操作, 如果modem超时没有被开启,还会等待modem开启中, 继续往这个队列里放入消息。
具体的实现关键点中发现timeout这个retry机制是发一个timeout的消息到队列里去处理 sendEmptyMessageDelayed(RETRY_TIMEOUTTIME_BETWEEN_RETRIES);
timeout 的时间是5s ,
TIME_BETWEEN_RETRIES = 5000; // msec
类EmergencyCallHelper承担这部分消息处理的逻辑以及收到消息后采取的措施,是继续开启modem还是拨打紧急电话。

第三方应用是不能影响,阻止拨打紧急电话的。

   不论是紧急电话还是正常的电话,第三方应用是在系统中拨出一个电话后是可以接到ACTION_NEW_OUTGOING_CALL 这样的一个intent的,SIP call除外; 系统中拨打的电话包括contacts / voice dialer / blue

本文标签: CallEmergencyandroid