实现“紧急呼叫”功能

从 2017 年 1 月 1 日开始,在印度地区销售的所有移动设备都必须应印度电信部门 (DoT) 的要求提供紧急按钮。为响应这些监管要求,Android 包含了“紧急呼叫”功能的参考实现,以启用 Android 设备上的紧急按钮。

此功能在 Android 8.0 及更高版本中默认启用,但在现有 build 的较早版本中必须安装相应的补丁。目前,该功能是专为印度市场销售的设备而开发;不过,鉴于该功能在印度境外无效,因此也可以在全球各地销售的所有设备上提供。

示例和源代码

“紧急呼叫”功能在 Android 开源项目 (AOSP) 的 frameworks/base 项目中实现。它在 main 分支中提供,并将在 Android 8.0 及更高版本中默认启用。

目前,以下分支和提交中已提供该功能。提供这些信息是为了方便设备制造商轻松将必要的更改以补丁程序的形式添加到现有 build 中。想要实现 AOSP 参考“紧急呼叫”功能的设备制造商可以从适用的分支中择优挑选提交内容并加入到自己的 build 中。

表 1. 择优挑选 AOSP 参考“紧急呼叫”功能

分支 提交
e0c3c66 添加了“紧急呼叫”功能
42a4338 添加了紧急操作字符串的翻译
4df8d64 修复了“紧急呼叫”在平板电脑上显示的问题
nougat-dev e6680d9 添加了“紧急呼叫”功能
95e1865 添加了紧急操作字符串的翻译
a70bb89 修复了“紧急呼叫”在平板电脑上显示的问题
marshmallow-dev cd22634 添加了“紧急呼叫”功能
13f51c6 添加了紧急操作字符串的翻译
6531666 修复了“紧急呼叫”在平板电脑上显示的问题
lollipop-mr1-dev 5fbc86b 添加了“紧急呼叫”功能
1b60879 添加了紧急操作字符串的翻译
d74366f 修复了“紧急呼叫”在平板电脑上显示的问题

实现

“紧急呼叫”功能不会更改通过 Android SDK 公开的 API。该功能启用并激活后,会提供两个可启动 112 紧急呼叫的触发器,112 是印度的唯一紧急电话号码,由印度电信部门强制实施。

紧急呼叫有两种启动方式:

长按锁定屏幕上的紧急呼叫
按钮
点按全局操作菜单中的紧急呼叫
选项
紧急呼叫按钮
图 1. 锁定屏幕上的紧急呼叫按钮。
紧急呼叫选项
图 2. 全局操作菜单上的紧急呼叫操作(长按电源键可访问)。

此功能引入了以下内部组件:

  • EmergencyAffordanceManager
    frameworks/base/core/java/com/android/internal/policy/EmergencyAffordanceManager.java
    
  • EmergencyAffordanceService
    frameworks/base/services/core/java/com/android/server/emergency/EmergencyAffordanceService.java
    

EmergencyAffordanceManager

EmergencyAffordanceManager 提供了使用“紧急呼叫”功能的内部 API。它提供启动紧急呼叫的方法,并在运行时查询是否应启用该功能。

  • void performEmergencyCall():启动紧急呼叫。
  • boolean needsEmergencyAffordance():确定是否应启用该功能。

该功能可在构建时永久停用,具体方法是将 EmergencyAffordanceManager.ENABLED 常量改为 false。这会导致 needsEmergencyAffordance() 始终返回 false 并阻止 EmergencyAffordanceService 启动。

EmergencyAffordanceService

EmergencyAffordanceService 是一项系统服务,用于监控所有检测到的移动网络的移动设备国家/地区代码 (MCC) 和已安装 SIM 卡的 MCC。如果任何已安装 SIM 卡或检测到的移动网络的 MCC 与印度的其中任一 MCC(404、405)相匹配,则该功能将会启用。这意味着,即使没有 SIM 卡,该功能也可以在印度启用。前提是,假设在没有安装 SIM 卡的情况下,移动网络允许注册紧急呼叫。该功能将保持启用状态,直到安装了非印度 SIM 卡且没有检测到具有匹配 MCC 的网络。

以下资源和设置会影响“紧急呼叫”功能的行为。如果配置类型是:

  • 资源,则是在 frameworks/base/core/res/res/values/config.xml 中定义的内部资源。
  • 设置,则是在系统设置提供程序中存储的设置。

表 2. 影响“紧急呼叫”功能行为的设置

配置类型 名称 说明
资源 config_emergency_call_number 在发起紧急呼叫时自动拨打的电话号码。
类型:字符串
默认值:112
资源 config_emergency_mcc_codes 列出能够激活该功能的预期 MCC 的整数数组。
类型:整数数组
默认值:{404,405}
设置 emergency_affordance_number 使用“紧急呼叫”致电号码的全局设置覆盖。此配置仅影响可调试的 build 映像(即 build 类型为 userdebug 或 eng)。此配置仅用于测试目的。
类型:字符串
默认值:未设置
设置 force_emergency_affordance 全局设置,指示是否显示“紧急呼叫”(无论设备状态如何)。此配置仅用于测试目的。
类型:布尔值(1 或 0)
默认值:未设置 --> 0

启用 112 紧急呼叫

“紧急呼叫”功能使用紧急拨号器连接通话,因此通话可以在锁屏状态下连接。紧急拨号器只能将通话连接到无线界面层 (RIL) 通过系统属性提供的号码列表:

  • 在未安装 SIM 卡时,通过系统属性 ril.ecclist 连接;
  • 在插入 SIM 卡且 SimSlotNumber 是默认订阅者的槽位 ID 时,通过系统属性 ril.ecclistSimSlotNumber 连接。

使用“紧急呼叫”功能的设备制造商必须确保在印度地区销售的设备始终将 112 作为 RIL 中的紧急电话号码。

验证

在可调试的 build 上测试时,可以使用以下命令更改呼叫的号码:

adb shell settings put global emergency_affordance_number NUMBER_TO_CALL

虽然此设置可以在常规 user build 中设置,但会被忽略。如需实际连接通话,号码必须存在于 RIL 提供的紧急电话号码列表中。此设置可以临时设置,具体方法是在 userdebug 设备上使用 root shell 执行以下命令:

setprop ril.ecclist "$(getprop ril.ecclist),NUMBER_TO_CALL"

此外,如需在未检测到印度移动网络或未插入印度 SIM 卡的情况下强制启用“紧急呼叫”功能,可以使用以下命令:

adb shell settings put global force_emergency_affordance 1

建议至少对以下情况进行测试:

  • 激活之后,长按锁定屏幕上的紧急呼叫按钮(图 1)可呼叫指定紧急电话号码。
  • 激活之后,全局操作菜单中会显示紧急呼叫选项,点按该选项可呼叫指定紧急电话号码。
  • 在未检测到印度移动网络且安装了非印度 SIM 卡的情况下,该功能不会激活
  • 在安装了印度 SIM 卡的情况下,无论是否检测到移动网络,该功能都会激活
  • 在检测到印度移动网络的情况下,无论是否安装了 SIM 卡,该功能都会激活

如果设备支持多个 SIM 卡,测试应检查 SIM 卡 MCC 检测功能是否能在每个 SIM 卡插槽中都正常运行。“紧急呼叫”功能不受 Android 兼容性影响,因此不用进行兼容性测试套件 (CTS) 测试。

常见问题解答

问:紧急电话号码“112”尚未在印度授权使用,仍然使用该号码吗?

根据集成紧急通信与应答系统 (IECRS) 的定义,112 是即将在印度用于公共安全应答点 (PSAP) 的号码。在 PSAP 获得授权之前,所有对 112 的呼叫都将转接到现有的 100 紧急电话号码(不过转接操作是由运营商进行,而不是由 Android 进行)。

问:使用其他触发操作怎么样?比如按电源按钮三次?

设备制造商可以选择实施其他触发操作。然而,虽然点按硬件电源按钮三次也是印度电信部门批准的触发操作,但这种触发操作在 AOSP 参考实现中不受支持,因为有部分其他广泛使用的应用(如相机应用)使用电源按钮手势,包括重复点按电源按钮。这些应用可能会干扰紧急拨号器,或者用户在尝试触发这些应用中的操作时可能会意外触发紧急按钮。