Android 11 平台包含可能影响您应用的行为变更。无论 targetSdkVersion
为何,以下行为变更都适用于在 Android 11 上运行的所有应用。您应该测试您的应用,然后根据需要进行修改,以妥善支持这些行为变更(如适用)。
请务必同时查看仅影响以 Android 11 为目标平台的应用的行为变更列表。
隐私
Android 11 引入了多项变更和限制,以增强用户隐私,包括以下内容:
- 一次性权限:让用户可以选择临时授予位置信息、麦克风和摄像头权限。
- 权限对话框可见性:重复拒绝权限意味着“不再询问”。
- 数据访问审核:深入了解您的应用在自身代码和依赖库代码中访问私人数据的位置。
- 系统提醒窗口权限:某些类别的应用在请求后会自动获得
SYSTEM_ALERT_WINDOW
权限。此外,包含ACTION_MANAGE_OVERLAY_PERMISSION
intent 操作的 intent 始终会将用户带到系统设置中的屏幕。 - 永久 SIM 卡标识符:在 Android 11 及更高版本上,通过
getIccId()
方法访问不可重置的 ICCID 受到限制。该方法会返回一个非 null 的空字符串。要唯一标识设备上已安装的 SIM 卡,请改用getSubscriptionId()
方法。订阅 ID 为唯一标识已安装的 SIM 卡(包括物理和电子 SIM 卡)提供一个索引值(从 1 开始)。除非设备恢复出厂设置,否则此标识符的值对于给定的 SIM 卡是稳定的。
要了解详情,请参阅隐私页面。
暴露通知
Android 11 更新了平台,考虑了暴露通知系统。用户现在可以在 Android 11 上运行暴露通知应用,而无需打开设备位置信息设置。这仅是暴露通知系统的一个例外,因为它设计成使用它的应用无法通过蓝牙扫描推断设备位置。
为了保护用户隐私,除非设备位置信息设置已打开且用户已授予位置信息权限,否则所有其他应用仍然禁止执行蓝牙扫描。您可以在我们的暴露通知更新博文中了解更多信息。
安全
SSL 套接字默认使用 Conscrypt SSL 引擎
Android 的默认 SSLSocket
实现基于 Conscrypt。自 Android 11 以来,该实现是在 Conscrypt 的 SSLEngine
之上内部构建的。
Scudo 加固分配器
Android 11 内部使用 Scudo Hardened Allocator 来处理堆分配。Scudo 能够检测和缓解某些类型的内存安全违规。如果您在原生崩溃报告中看到与 Scudo 相关的崩溃(例如,Scudo ERROR:
),请参阅 Scudo 疑难解答文档。
应用使用情况统计信息
为了更好地保护用户,Android 11 将每个用户的应用使用情况统计信息存储在凭据加密存储中。因此,除非 isUserUnlocked()
返回 true
(发生在以下任一情况之后),否则系统和任何应用都无法访问该数据:
- 系统启动后,用户首次解锁其设备。
- 用户切换到设备上的其帐户。
如果您的应用已绑定到 UsageStatsManager
的实例,请确保在用户解锁设备后调用此对象上的方法。否则,API 现在将返回 null 或空值。
模拟器支持 5G
Android 11 添加了 5G API,使您的应用能够添加尖端功能。要在添加功能时进行测试,您可以使用 Android SDK 模拟器的新功能。新功能已在模拟器版本 30.0.22 中添加。选择 5G 网络设置会将 TelephonyDisplayInfo
设置为 OVERRIDE_NETWORK_TYPE_NR_NSA
,修改估算带宽,并允许您设置计量状态以验证您的应用是否对 NET_CAPABILITY_TEMPORARILY_NOT_METERED
状态的变化做出适当响应。
性能和调试
JobScheduler API 调用限制调试
Android 11 为应用提供了调试支持,以识别可能已超出某些速率限制的 JobScheduler
API 调用。开发者可以使用此功能来识别潜在的性能问题。对于 debuggable
清单属性设置为 true 的应用,超出速率限制的 JobScheduler
API 调用将返回 RESULT_FAILURE
。设置的限制不会影响合法用例。
文件描述符清理工具 (fdsan)
Android 10 引入了 fdsan
(文件描述符清理工具)。fdsan
检测文件描述符所有权处理不当,例如使用后关闭和双重关闭。Android 11 中 fdsan
的默认模式正在改变。fdsan
现在在检测到错误时会中止;以前的行为是记录警告并继续。如果您在应用程序中看到因 fdsan
导致的崩溃,请参阅 fdsan documentation
。
非 SDK 接口限制
Android 11 包含根据与 Android 开发者的协作和最新的内部测试更新的受限制非 SDK 接口列表。在可能的情况下,我们确保在限制非 SDK 接口之前提供公共替代方案。
如果您的应用不以 Android 11 为目标平台,其中一些更改可能不会立即影响您。但是,虽然您目前可以使用某些非 SDK 接口(取决于您的应用的目标 API 级别),但使用任何非 SDK 方法或字段始终存在导致您的应用崩溃的高风险。
如果您不确定您的应用是否使用非 SDK 接口,可以测试您的应用以找出答案。如果您的应用依赖于非 SDK 接口,您应该开始计划迁移到 SDK 替代方案。尽管如此,我们理解某些应用有使用非 SDK 接口的有效用例。如果您无法找到替代方案以在您的应用中为某个功能使用非 SDK 接口,您应该请求新的公共 API。
要了解有关此 Android 版本中更改的更多信息,请参阅Android 11 中非 SDK 接口限制的更新。要了解有关非 SDK 接口的总体信息,请参阅非 SDK 接口的限制。
Maps v1 共享库已移除
Maps 共享库的 V1 版已在 Android 11 中完全移除。此库之前已被弃用,并且在 Android 10 中对应用停止运行。之前依赖此共享库在运行 Android 9 (API 级别 28) 或更低版本的设备上运行的应用应改用 Maps SDK for Android。
与其他应用的交互
共享内容 URI
如果您的应用与另一个应用共享内容 URI,则 intent 必须通过设置以下至少一个 intent 标志来授予 URI 访问权限:FLAG_GRANT_READ_URI_PERMISSION
和 FLAG_GRANT_WRITE_URI_PERMISSION
。这样,如果其他应用以 Android 11 为目标平台,它仍然可以访问内容 URI。即使内容 URI 与您的应用不拥有的内容提供程序相关联,您的应用也必须包含这些 intent 标志。
如果您的应用拥有与内容 URI 相关联的内容提供程序,请验证内容提供程序未导出。我们已经建议此安全最佳实践。
库加载
使用绝对路径加载 ICU common 库
以 API 28 及更低版本为目标平台的应用无法使用 dlopen(3)
以绝对路径 "/system/lib/libicuuc.so" 加载 libicuuc
。对于这些应用,dlopen("/system/lib/libicuuc.so", ...)
将返回 null 句柄。
相反,要加载库,请使用库名称作为文件名,例如 dlopen("libicuuc.so", ...)
。