设备标识符

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

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

此项更改会影响以下 API:

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

在 Google Play 中,不使用运营商权限的运营商应用无法再访问设备标识符。如果运营商的应用作为特权应用预加载在设备上,则需要使用 READ_PRIVILEGED_PHONE_STATE 权限才能访问设备标识符。

实现

请更新您的特许权限白名单,以向需要访问设备标识符的特权应用授予 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.UNKNOWN(调用 Build#getSerial 方法之后)。
  • 如果应用以 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