Google 致力于为黑人社区推动种族平等。查看具体举措

设备标识符

Android 10 更改了设备标识符的权限,让所有设备标识符现在都受到 READ_PRIVILEGED_PHONE_STATE 权限的保护。在 Android 10 之前的版本中,永久性设备标识符(IMEI/MEID、IMSI、SIM 和 build 序列号)受到 READ_PHONE_STATE 运行时权限的保护。系统仅会向使用平台密钥进行签名的应用以及特权系统应用授予 READ_PRIVILEGED_PHONE_STATE 权限。

如需详细了解新的权限要求,请访问 TelephonyManager.javaBuild.java 这两个 Javadoc 页面。

此项更改会影响以下 API:

  • TelephonyManager#getDeviceId
  • TelephonyManager#getImei
  • TelephonyManager#getMeid
  • TelephonyManager#getSimSerialNumber
  • TelephonyManager#getSubscriberId
  • Build#getSerial

不具备 READ_PRIVILEGED_PHONE_STATE 权限的运营商应用的访问权限

不符合 READ_PRIVILEGED_PHONE_STATE 权限条件的预加载运营商应用可以实现下表中的某个选项。

选项 说明 限制
UICC 运营商权限 Android 平台会加载存储在 UICC 上的证书,并向由这些证书签名的应用授予权限,以允许其调用特殊的方法。 传统运营商已建立的 SIM 卡数量庞大,不易更新。此外,对于新 SIM 卡没有创作权的运营商(例如拥有 MNO 发行的 SIM 卡的 MVNO)无法在 SIM 卡上添加或更新证书。
OEM 白名单 OEM 可以使用 OP_READ_DEVICE_IDENTIFIER 向已列入白名单的运营商应用提供设备标识符。 此解决方案仅适用于部分运营商。
类型分配码 (TAC) 可使用 Android 10 中引入的 getTypeAllocationCode 方法公开 TAC,该 TAC 可返回制造商和型号信息。 TAC 中的信息不足以识别具体设备。
MSISDN 运营商可以使用具有 PHONE 权限组的 TelephonyManager 下的电话号码 (MSISDN) 在其后端系统上查询 IMEI。 这需要运营商做出巨额投入。对于使用 IMSI 映射网络密钥的运营商而言,切换到 MSISDN 需要大量的技术资源。

所有运营商应用都可以使用各自的签名证书哈希值更新 CarrierConfig.xml 文件,通过这种方法访问设备标识符。当运营商应用调用某个方法读取具有特权的信息时,平台会在 CarrierConfig.xml 文件中查找应用的匹配签名证书哈希值(证书的 SHA-1 或 SHA-256 签名)。如果找到匹配项,会返回所请求的信息。如果未找到匹配项,则返回安全异常。

如需实现此解决方案,运营商必须按以下步骤操作:

  1. 使用运营商应用的签名证书哈希值更新 CarrierConfig.xml,并提交补丁程序
  2. 请求 OEM 使用 QPR1+(推荐)或必需的平台补丁程序以及上述第 1 步中包含更新后的 CarrierConfig.xml 文件的补丁程序来更新其 build。

实现

请更新您的特许权限白名单,以便向需要访问设备标识符的特权应用授予 READ_PRIVILEGED_PHONE_STATE 权限。

如需详细了解如何加入白名单,请参阅特许权限白名单

如需调用受影响的 API,应用必须满足以下要求之一:

  • 如果应用是预加载的特权应用,则需要获得在 AndroidManifest.xml 中声明的 READ_PRIVILEGED_PHONE_STATE 权限。此外,该应用还需要将此特许权限列入白名单。
  • 通过 Google Play 提供的应用需要运营商权限。请访问 UICC 运营商权限页面,详细了解如何授予运营商权限。
  • 应用是已获得 READ_PHONE_STATE 权限的设备所有者或资料所有者应用。

不符合上述任何要求的应用具有以下行为:

  • 如果应用以 Android Q 之前的版本为目标平台,且未获得 READ_PHONE_STATE 权限,则会触发 SecurityException。这是 Android Q 之前的版本目前会出现的行为,因为调用这些 API 需要此权限。
  • 如果应用以 Android Q 之前的版本为目标平台,且已获得 READ_PHONE_STATE 权限,则会在调用所有 TelephonyManager API 之后收到 null 值,还会在调用 Build#getSerial 方法之后收到 Build.UNKNOWN
  • 如果应用以 Android 10 或更高版本为目标平台,且不符合任何一项新要求,则会收到 SecurityException。

验证和测试

兼容性测试套件 (CTS) 包含用于验证以下应用的预期设备标识符访问行为的测试:具有运营商权限的应用、设备所有者和资料所有者应用以及预计无权访问设备标识符的应用。

以下 CTS 测试专门针对此功能。

cts-tradefed run cts -m CtsCarrierApiTestCases -t
    android.carrierapi.cts.CarrierApiTest

cts-tradefed run cts -m CtsTelephonyTestCases -t
    android.telephony.cts.TelephonyManagerTest

cts-tradefed run cts -m CtsTelephony3TestCases

cts-tradefed run cts -m CtsPermissionTestCases -t
    android.permission.cts.TelephonyManagerPermissionTest

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCanGetDeviceIdentifiers

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCanGetDeviceIdentifiers

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCannotGetDeviceIdentifiersWithoutPermission

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCannotGetDeviceIdentifiersWithoutPermission