Android 11 引入了一些变更和限制来加强用户隐私保护,其中包括:
SYSTEM_ALERT_WINDOW
权限。此外,包含 ACTION_MANAGE_OVERLAY_PERMISSION
intent 操作的 intent 始终会将用户转至系统设置中的屏幕。getIccId()
方法访问不可重置的 ICCID 受到限制。该方法会返回一个非 null 的空字符串。如需唯一标识设备上安装的 SIM 卡,请改用 getSubscriptionId()
方法。订阅 ID 会提供一个索引值(从 1 开始),用于唯一识别已安装的 SIM 卡(包括实体 SIM 卡和电子 SIM 卡)。除非设备恢复出厂设置,否则此标识符的值对于给定 SIM 卡是保持不变的。 在 Android 11(API 级别 30)上运行但以 Android 10(API 级别 29)为目标平台的应用仍可请求 requestLegacyExternalStorage
属性。应用可以利用此标记暂时停用与分区存储相关的变更,例如授予对不同目录和不同类型的媒体文件的访问权限。当您将应用更新为以 Android 11 (targetSdkVersion = 30)为目标平台后,系统会忽略 requestLegacyExternalStorage
标记。
如果应用在 Android 10 设备上运行时选择退出分区存储,建议您继续在应用的清单文件中将 requestLegacyExternalStorage
设为 true。这样,应用就可以在运行 Android 10 的设备上继续按预期运行。
如果您的应用使用旧版存储模型且之前以 Android 10 或更低版本为目标平台,您可能会将数据存储到启用分区存储模型后您的应用无法访问的目录中。在以 Android 11 为目标平台之前,请将数据迁移到与分区存储兼容的目录。
附:Android 存储用例和最佳做法
从 Android 11 开始,使用分区存储模型的应用只能访问自身的应用专用缓存文件。如果您的应用需要管理设备存储空间,请按照关于如何查询可用空间的说明操作。
ACTION_MANAGE_STORAGE
intent 操作检查可用空间。ACTION_CLEAR_APP_CACHE
intent 操作。注意:
ACTION_CLEAR_APP_CACHE
intent 操作会严重影响设备的电池续航时间,并且可能会从设备上移除大量的文件。
从 Android 11 开始,应用无法在外部存储设备上创建自己的应用专用目录。如需访问系统为您的应用提供的目录,请调用 getExternalFilesDirs()
。
为了帮助您的应用更顺畅地使用第三方媒体库,Android 11 允许您使用除 MediaStore API 之外的 API 通过直接文件路径访问共享存储空间中的媒体文件。其中包括:
Android 9(API 级别 28)开始限制哪些应用可使其内部存储设备上数据目录中的文件可由其他应用进行全局访问。以 Android 9 或更高版本为目标平台的应用不能使其数据目录中的文件全局可访问。Android 11 在此限制的基础上进行了扩展。如果您的应用以 Android 11 为目标平台,则不能访问其他任何应用的数据目录中的文件,即使其他应用以 Android 8.1(API 级别 27)或更低版本为目标平台且已使其数据目录中的文件全局可读也是如此。
在 Android 11 上,应用无法再访问外部存储设备中的任何其他应用的专用于特定应用的目录中的文件。
应用以 Android 11 或更高版本为目标平台时。
ACTION_OPEN_DOCUMENT_TREE
intent 操作请求访问以下目录:
- 内部存储卷的根目录。
- 设备制造商认为可靠的各个 SD 卡卷的根目录,无论该卡是模拟卡还是可移除的卡。可靠的卷是指应用在大多数情况下可以成功访问的卷。
Download
目录。
ACTION_OPEN_DOCUMENT_TREE
或 ACTION_OPEN_DOCUMENT
intent 操作请求用户从以下目录中选择单独的文件:
Android/data/
目录及其所有子目录。Android/obb/
目录及其所有子目录。
如果应用以 Android 11 为目标平台,那么 WRITE_EXTERNAL_STORAGE
权限和 WRITE_MEDIA_STORAGE
特许权限将不再提供任何其他访问权限。
请注意,在搭载 Android 10(API 级别 29)或更高版本的设备上,您的应用可以提供明确定义的媒体集合,例如 MediaStore.Downloads,而无需请求任何存储相关权限。详细了解如何在处理应用中的媒体文件时仅请求必要的权限。
不管应用的目标 SDK 版本是什么,以下变更均会在 Android 11 中生效:
READ_EXTERNAL_STORAGE
权限,用户会看到不同于 Android 10 的对话框。该对话框表明您的应用正在请求访问照片和媒体。READ_EXTERNAL_STORAGE
权限。在设置 > 隐私 > 权限管理器 > 文件
和媒体页面
上,具有该权限的每个应用都列在允许存储所有文件下。如果您的应用以 Android 11 为目标平台,请记住,对“所有文件”的这种访问权限是只读访问权限。如需使用此应用读取和写入共享的存储空间中的所有文件,需要具有所有文件访问权限。在 Android 11 中,用户能够针对位置信息、麦克风和摄像头指定更精细的权限。此外,如果以 Android 11 或更高版本为目标平台的应用在一段时间内未使用,系统就会重置这些应用的权限。如果应用使用系统提醒窗口或读取与电话号码相关的信息,可能需要更新它们声明的权限。
从 Android 11(API 级别 30)开始,每当应用请求与位置信息、麦克风或相机相关的权限时,面向用户的权限对话框会包含仅限这一次选项。如果用户在对话框中选择此选项,系统会向应用授予临时的单次授权。
然后,应用可以在一段时间内访问相关数据,具体时间取决于应用的行为和用户的操作:
- 当应用的 Activity 可见时,应用可以访问相关数据。
- 如果用户将应用转为后台运行,应用可以在短时间内继续访问相关数据。
- 如果您在 Activity 可见时启动了一项前台服务,并且用户随后将您的应用转到后台,那么您的应用可以继续访问相关数据,直到该前台服务停止。
- 如果用户撤消单次授权(例如在系统设置中撤消),无论您是否启动了前台服务,应用都无法访问相关数据。与任何权限一样,如果用户撤消了应用的单次授权,应用进程就会终止。
当用户下次打开应用并且应用中的某项功能请求访问位置信息、麦克风或摄像头时,系统会再次提示用户授予权限。
注意:如果应用在请求运行时权限时已遵循最佳做法,您无需在应用中添加或更改任何逻辑即可支持单次授权。
如果应用以 Android 11 或更高版本为目标平台并且数月未使用,系统会通过自动重置用户已授予应用的运行时敏感权限来保护用户数据。此操作与用户在系统设置中查看权限并将应用的访问权限级别更改为拒绝的做法效果一样。如果应用遵循了有关在运行时请求权限的最佳做法,那么您不必对应用进行任何更改。这是因为,当用户与应用中的功能互动时,您应该会验证相关功能是否具有所需权限。
注意:系统仅重置运行时权限,在请求这些权限时,系统会向用户显示运行时提示。
从 Android 11 开始,在应用安装到设备上后,如果用户在使用过程中多次针对某项特定的权限点按拒绝,那么在您的应用再次请求该权限时,用户将不会看到系统权限对话框。该操作表示用户希望“不再询问”。在之前的版本中,除非用户先前已选中“不再询问”对话框或选项,否则每当您的应用请求权限时,用户都会看到系统权限对话框。Android 11 中的这一行为变更旨在避免重复请求用户已选择拒绝的权限。
在 Android 11 中,向应用授予 SYSTEM_ALERT_WINDOW
权限的方式发生了一些变更。这些变更可以让权限的授予更有目的性,从而达到保护用户的目的。
根据请求自动向某些应用授予 SYSTEM_ALERT_WINDOW
权限
系统会根据请求自动向某些类型的应用授予 SYSTEM_ALERT_WINDOW
权限:
- 系统会自动向具有
ROLE_CALL_SCREENING
且请求SYSTEM_ALERT_WINDOW
的所有应用授予该权限。如果应用失去ROLE_CALL_SCREENING
,就会失去该权限。- 系统会自动向通过
MediaProjection
截取屏幕且请求SYSTEM_ALERT_WINDOW
的所有应用授予该权限,除非用户已明确拒绝向应用授予该权限。当应用停止截取屏幕时,就会失去该权限。此用例主要用于游戏直播应用。
这些应用无需发送 ACTION_MANAGE_OVERLAY_PERMISSION
以获取 SYSTEM_ALERT_WINDOW
权限,它们只需直接请求 SYSTEM_ALERT_WINDOW
即可。
MANAGE_OVERLAY_PERMISSION
intent 始终会将用户转至系统权限屏幕
从 Android 11 开始,ACTION_MANAGE_OVERLAY_PERMISSION
intent 始终会将用户转至顶级设置屏幕,用户可在其中授予或撤消应用的 SYSTEM_ALERT_WINDOW
权限。intent 中的任何 package: 数据都会被忽略。
在更低版本的 Android 中,ACTION_MANAGE_OVERLAY_PERMISSION
intent 可以指定一个软件包,它会将用户转至应用专用屏幕以管理权限。从 Android 11 开始将不再支持此功能,而是必须由用户先选择要授予或撤消哪些应用的权限。此变更可以让权限的授予更有目的性,从而达到保护用户的目的。
Android 11 更改了您的应用在读取电话号码时使用的与电话相关的权限。
如果您的应用以 Android 11 或更高版本为目标平台,并且需要访问以下列表中显示的电话号码 API,则必须请求 READ_PHONE_NUMBERS
权限,而不是 READ_PHONE_STATE
权限。
TelephonyManager
类和TelecomManager
类中的getLine1Number()
方法。TelephonyManager
类中不受支持的getMsisdn()
方法。
如果您的应用声明 READ_PHONE_STATE
以调用前面列表中的方法以外的方法,您可以继续在所有 Android 版本中请求 READ_PHONE_STATE
。不过,如果您仅对前面列表中的方法使用 READ_PHONE_STATE
权限,请按以下方式更新您的清单文件:
1、更改
READ_PHONE_STATE
的声明,以使您的应用仅在 Android 10(API 级别 29)及更低版本中使用该权限。
2、添加READ_PHONE_NUMBERS
权限。
以下清单声明代码段演示了此过程:
同单次授权
在 Android 10(API 级别 29)及更高版本中,您必须在应用的清单中声明 ACCESS_BACKGROUND_LOCATION
权限,以便请求在运行时于后台访问位置信息。在较低版本的 Android 系统中,当应用获得前台位置信息访问权限时,也会自动获得后台位置信息访问权限。
当应用中的功能需要位置信息访问权限时,请等到用户与该功能互动时再发出权限请求。本工作流遵循在上下文中请求运行时权限的最佳做法。如果应用以 Android 11(API 级别 30)或更高版本为目标平台,系统会强制执行此最佳做法。如果您同时请求在前台访问位置信息的权限和在后台访问位置信息的权限,系统会忽略该请求,且不会向您的应用授予其中的任一权限。
Android 11 更改了应用查询用户已在设备上安装的其他应用以及与之交互的方式。使用
元素,应用可以定义一组自身可访问的其他软件包。通过告知系统应向您的应用显示哪些其他软件包,此元素有助于鼓励最小权限原则。此外,此元素还可帮助 Google Play 等应用商店评估应用为用户提供的隐私权和安全性。
如果您的应用以 Android 11 或更高版本为目标平台,您可能需要在应用的清单文件中添加
元素。在
元素中,您可以按软件包名称、intent 签名或提供程序授权指定软件包。
注意:即使您的应用以 Android 11 或更高版本为目标平台,某些应用也会自动对您的应用可见。如需详细了解您应用的用例如何受到影响以及如何更新您的应用,请参阅有关如何根据用例配置软件包可见性的指南。
为了让应用及其依赖项访问用户私密数据的过程更加透明,Android 11 引入了数据访问审核功能。借助此流程得出的见解,您可以更好地识别可能出现的意外数据访问。您的应用可以注册 AppOpsManager.OnOpNotedCallback 实例,该实例可在每次发生以下任一事件时执行相应操作:
如需了解详情,请参阅有关如何审核对数据的访问权限的指南。
MAC 地址具有全局唯一性,无法由用户重置,在恢复出厂设置后也不会变化。因此,一般不建议使用 MAC 地址进行任何形式的用户标识。搭载 Android 10(API 级别 29)及更高版本的设备会报告不是设备所有者应用的所有应用的随机化 MAC 地址。
在 Android 6.0(API 级别 23)到 Android 9(API 级别 28)中,本地设备 MAC 地址(如 WLAN 和蓝牙)无法通过第三方 API 使用。WifiInfo.getMacAddress()
方法和 BluetoothAdapter.getDefaultAdapter().getAddress()
方法都会返回 02:00:00:00:00:00。
此外,在 Android 6.0 到 Android 9 版本中,您还必须拥有下列权限,才能访问通过蓝牙和 WLAN 扫描获得的附近外部设备的 MAC 地址:
方法/属性 | 所需权限 |
---|---|
WifiManager.getScanResults() | ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION |
BluetoothDevice.ACTION_FOUND | ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION |
BluetoothLeScanner.startScan(ScanCallback) | ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION |
本指南剩下的部分将以开发 Android 应用为背景详细介绍这些规则。
注意:在使用 Android 标识符时,请不要使用 MAC 地址,并遵循以下最佳做法:
- 避免使用硬件标识符。在大多数用例中,您可以避免使用硬件标识符,例如 SSAID (Android ID),而不会限制所需的功能。
Android 10(API 级别 29)对不可重置的标识符(包括 IMEI 和序列号)添加了限制。您的应用必须是设备或个人资料所有者应用,具有特殊运营商权限或具有READ_PRIVILEGED_PHONE_STATE
特许权限,才能访问这些标识符。- 只针对用户剖析或广告用例使用广告 ID。在使用广告 ID 时,请始终遵循用户关于广告跟踪的选择。此外,请确保标识符无法关联到个人身份信息 (PII),并避免桥接广告 ID 重置。
- 尽一切可能针对防欺诈支付和电话以外的所有其他用例使用实例 ID 或私密存储的 GUID。对于绝大多数非广告用例,使用实例 ID 或 GUID 应已足够。
- 使用适合您的用例的 API 以尽量降低隐私权风险。使用 DRM API 保护重要内容,并使用 SafetyNet API 防止滥用行为。SafetyNet API 是能够确定设备真伪而不会招致隐私权风险的最简单方法。
详见唯一标识符最佳做法
在 Android 11 中,前台服务何时可以访问设备的位置信息、摄像头和麦克风发生了一些变化。这有助于保护敏感的用户数据。
camera
和 microphone
如果您的应用以 Android 11 或更高版本为目标平台,且在前台服务中访问摄像头或麦克风,则必须添加前台服务类型 camera
和 microphone
。
Notification notification = ...;
Service.startForeground(notification,
FOREGROUND_SERVICE_TYPE_LOCATION | FOREGROUND_SERVICE_TYPE_CAMERA);
//FOREGROUND_SERVICE_TYPE_LOCATION
//FOREGROUND_SERVICE_TYPE_CAMERA
//FOREGROUND_SERVICE_TYPE_MICROPHONE
...
如果您的应用在后台运行时启动了某项前台服务,则该前台服务无法访问麦克风或摄像头。此外,除非您的应用具有在后台访问位置信息的权限,否则该服务无法访问位置信息。
详细了解如何在应用中使用前台服务。
Android 11 包含一个新的 ControlsProviderService
API,可用于提供所连接的外部设备的控件。这些控件显示于 Android 电源菜单中的设备控制器下。如需了解详情,请参阅控制外部设备。
Android 11 更新了媒体控件的显示方式。媒体控件显示于快捷设置旁。来自多个应用的会话排列在一个可滑动的轮播界面中,其中包括在手机本地播放的会话流、远程会话流(例如在外部设备上检测到的会话或投射会话)以及可继续播放的以前的会话(按上次播放的顺序排列)。
用户无需启动相关应用即可在轮播界面中重新开始播放以前的会话。当播放开始后,用户可按常规方式与媒体控件互动。
如需了解详情,请参阅媒体控件。
Android 11 提供了一些 API 以支持瀑布屏,这是一种无边框的全面屏。这种显示屏被视为刘海屏的变体。现有的 DisplayCutout.getSafeInset…()
方法现在会返回能够避开瀑布区域以及刘海的安全边衬区。如需在瀑布区域中呈现您的应用内容,请执行以下操作:
调用
DisplayCutout.getWaterfallInsets()
以获取瀑布边衬区的精确尺寸。将窗口布局属性
layoutInDisplayCutoutMode
设为LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
,以允许窗口延伸到屏幕各个边缘上的刘海和瀑布区域。您必须确保刘海或瀑布区域中没有重要的内容。注意:如果您未将上述窗口布局属性设为
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
,Android 会在黑边模式下显示窗口,从而避开缺口和瀑布区域。
使用 Android 11,可以通过以下方法使运行在采用合页式屏幕配置的设备上的应用能够确定合页角度:提供具有 TYPE_HINGE_ANGLE
的新传感器,以及新的 SensorEvent
,后者可以监控合页角度,并提供设备的两部分之间的角度测量值。您可以使用这些原始测量值在用户操作设备时执行精细的动画显示。
请参阅可折叠设备。
Android 11 对会话的处理方式进行了多项改进。会话是两人或更多人之间的实时双向通信。这些会话具有特殊的重要性,并且用户在如何与其进行交互方面有多个新的选项可以选择。
如需详细了解对话以及您的应用如何支持对话,请参阅人与对话。
现已面向开发者推出气泡功能,该功能有助于在系统中显示会话。对话泡是 Android 10 中的一项实验性功能,通过开发者选项启用;在 Android 11 中,这项功能不再是必选功能。
如果应用以 Android 11(API 级别 30)或更高版本为目标平台,除非其通知满足新的对话要求,否则不会以Android 10对话泡形式显示。具体而言,通知必须与快捷方式关联。
在 Android 11 之前,如果您希望通知以气泡形式显示,需要明确指定将其设为始终在文档界面模式下启动。从 Android 11 开始,您不再需要明确进行这项设置;如果通知以对话泡形式显示,平台会自动将其设为始终在文档界面模式下启动。
对话泡功能有多项改进,用户可以更灵活地在每个应用中启用和停用对话泡功能。对于实现了实验性支持的开发者,Android 11 中的 API 有一些变更:
- 不带参数的
BubbleMetadata.Builder()
构造函数已弃用。请改为使用BubbleMetadata.Builder(PendingIntent, Icon)
或BubbleMetadata.Builder(String)
这两个新构造函数中的任意一个。- 通过调用
BubbleMetadata.Builder(String)
,根据快捷方式 ID 创建BubbleMetadata
。传递的字符串应与提供给Notification.Builder
的快捷方式 ID 一致。- 使用
Icon.createWithContentUri()
或新方法createWithAdaptiveBitmapContentUri()
创建气泡图标。
Android 11 添加了在您的应用中支持 5G 的功能。如何改善用户体验。请参阅在向您的应用添加 5G 功能。
为了帮助您控制应用数据的安全级别,Android 11 对生物识别身份验证机制进行了多项改进。这些变更也会在 Jetpack Biometric 库中显示。
Android 11 引入了 BiometricManager.Authenticators 接口,可用于声明您的应用支持的身份验证类型。
在用户进行身份验证后,您可以通过调用 getAuthenticationType() 检查用户是使用设备凭据还是生物识别凭据进行的身份验证。
Android 11 提供了对“每次使用时进行身份验证”密钥的更多支持。
Android 11 弃用了以下方法:
setDeviceCredentialAllowed()
方法。setUserAuthenticationValidityDurationSeconds()
方法。不带任何参数的 canAuthenticate()
过载版本。
在某些情况下,例如涉及机器学习或媒体播放时,您的应用可能需要与其他应用使用同一个大型数据集。在较早的 Android 版本中,您的应用与其他应用需要各自单独下载该数据集。
为帮助减少网络中和磁盘上的数据冗余,Android 11 允许使用共享数据 blob 在设备上缓存这些大型数据集。如需详细了解如何共享数据集,请参阅有关共享大型数据集的深度指南。
设备完成 OTA 更新并重启后,放在受凭据保护的存储空间中的凭据加密 (CE) 密钥可立即用于执行文件级加密 (FBE) 操作。这意味着,完成 OTA 更新后,您的应用可以在用户输入其 PIN 码、解锁图案或密码之前恢复需要 CE 密钥的操作。
注意:此变更仅影响因 OTA 更新而发生的设备重启。如果您的应用在设备重启后用户输入其 PIN 码、解锁图案或密码之前始终需要访问 CE 密钥,请继续支持直接启动。
Android 11 支持通过 Android 调试桥 (adb) 从工作站以无线方式部署和调试应用。例如,您可以将可调试的应用部署到多台远程设备,而无需通过 USB 实际连接您的设备,从而避免常见的 USB 连接问题(例如驱动程序安装方面的问题)。
如需使用无线调试,您需要使用配对码将您的设备与工作站配对。您的工作站和设备必须连接到同一无线网络。如需连接到您的设备,请按以下步骤操作:
- 无线 adb 配对对话框
- 在您的工作站上,更新到最新版本的 SDK 平台工具。
- 在设备上启用开发者选项。
- 启用无线调试选项。
- 在询问要在此网络上允许无线调试吗?的对话框中,点击允许。
- 选择使用配对码配对设备。记下设备上显示的配对码、IP 地址和端口号(参见图片)。
- 在工作站上,打开一个终端并导航到 android_sdk/platform-tools。
- 运行 adb pair ipaddr:port。使用第 5 步中的 IP 地址和端口号。
- 当系统提示时,输入您在第 5 步中获得的配对码。系统会显示一条消息,表明您的设备已成功配对。
- (仅适用于 Linux 或 Microsoft Windows)运行
adb connect ipaddr:port
。使用无线调试下的 IP 地址和端口。
在设备上安装大型(2GB 以上)APK 可能需要很长的时间,即使应用只是稍作更改也是如此。ADB(Android 调试桥)增量 APK 安装可以安装足够的 APK 以启动应用,同时在后台流式传输剩余数据,从而加速这一过程。如果设备支持该功能,并且您安装了最新的 SDK 平台工具,adb install 将自动使用此功能。如果不支持,系统会自动使用默认安装方法。
运行以下 adb 命令以使用该功能。如果设备不支持增量安装,该命令将会失败并输出详细的解释。
adb install --incremental
在运行 ADB 增量 APK 安装之前,您必须先为 APK 签名并创建一个 APK 签名方案 v4 文件。必须将 v4 签名文件放在 APK 旁边,才能使此功能正常运行。
GWP-ASan是一种原生内存分配器功能,可帮助查找释放后使用和堆缓冲区溢出错误。您可以全局启用此功能,也可以为应用的特定子进程启用此功能。如需了解详情,请参阅 GWP-Asan 指南。
Android 11 扩展并改进了 Neural Networks API (NNAPI)。
NNAPI 1.3 引入了新的运算数类型 TENSOR_QUANT8_ASYMM_SIGNED
,还引入了以下新运算:
QUANTIZED_LSTM
IF
WHILE
ELU
HARD_SWISH
FILL
RANK
NNAPI 1.3 引入了新控件以帮助机器学习流畅运行。
在 Android 11 中使用 NDK Thermal API 监控设备上的温度变化,然后采取相应措施以降低耗电量和设备温度。该 API 类似于Java Thermal API;您可以使用它接收任何热状态更改的通知或直接轮询当前状态。
Android 11 引入了新的 API 以改进输入法 (IME) 的转换,例如屏幕键盘。这些 API 可让您更轻松地调整应用内容,与 IME 的出现和消失以及状态和导航栏等其他元素保持同步。
方法 | 作用 |
---|---|
view.getInsetsController().show(Type.ime()) |
显示 IME |
view.getInsetsController().hide(Type.ime()) |
隐藏 IME |
view.getRootWindowInsets().isVisible(Type.ime()) |
检查 IME 当前是否可见 |
注:您可以在与聚焦的 EditText 相同层次结构中的任何视图上调用此方法,无需专门在
EditText
上调用它
如需同步应用的视图与 IME 的显示和消失,请通过提供 WindowInsetsAnimation.Callback
到 View.setWindowInsetsAnimationCallback()
在视图上设置监听器(您可以在任何视图上设置该监听器,它不一定必须为 EditText
)。IME 会调用监听器的 onPrepare()
方法,之后会在转换开始时调用 onStart()
。然后,它会在每次转换的过程中调用 onProgress()
。转换完成后,IME 会调用 onEnd()
。在转换过程中,您随时可以调用 WindowInsetsAnimation.getFraction()
以了解转换的进度。
有关如何使用这些 API 的示例,请参阅新的 WindowInsetsAnimation 代码示例。
您还可以控制 IME 动画或其他系统栏(如导航栏)的动画。如需执行此操作,请先调用 setOnApplyWindowInsetsListener()
,为窗口边衬区更改设置新的监听器:
//KOTLIN
rootView.setOnApplyWindowInsetsListener { rootView, windowInsets ->
val barsIme = windowInsets.getInsets(Type.systemBars() or Type.ime())
rootView.setPadding(barsIme.left, barsIme.top, barsIme.right,
barsIme.bottom)
// 返回WindowInsets.CONSUMED,来阻止inset进一步分派到视图层次结构中。以替换不推荐使用的WindowInsets.consumeSystemWindowInsets()和相关函数。
WindowInsets.CONSUMED
}
//JAVA
mRoot.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
Insets barsIME = insets.getInsets(Type.systemBars() | Type.ime());
mRootView.setPadding(barsIme.left, barsIme.top, barsIme.right,
barsIme.bottom);
// We return the new WindowInsets.CONSUMED to stop the insets being
// dispatched any further into the view hierarchy. This replaces the
// deprecated WindowInsets.consumeSystemWindowInsets() and related
// functions.
return WindowInsets.CONSUMED;
}
});
如需移动 IME 或其他系统栏,请调用控制器的 controlWindowInsetsAnimation()
方法:
//KOTLIN
view.windowInsetsController.controlWindowInsetsAnimation(
Type.ime(),
1000,
LinearInterpolator(),
cancellationSignal,
object : WindowInsetsAnimationControlListener() {
fun onReady(controller: WindowInsetsAnimationController,
types: Int) {
// update IME inset
controller.setInsetsAndAlpha(Insets.of(0, 0, 0, inset),
1f /* alpha */, 0.1 /* fraction progress */)
}
}
);
//JAVA
mRoot.getWindowInsetsController().controlWindowInsetsAnimation(
Type.ime(), 1000, new LinearInterpolator(), cancellationSignal,
new WindowInsetsAnimationControlListener() {
@Override
public void onReady(
@NonNull WindowInsetsAnimationController controller,
int types
) {
// update IME inset
controller.setInsetsAndAlpha(Insets.of(0, 0, 0, inset),
1f /* alpha */, 0.1 /* fraction progress */);
}
@Override
public void onCancelled() {}
});
Android 11 更新了 android.icu
软件包,以使用 ICU 库版本 66,而 Android 10 中使用的是版本 63。新版库包含更新的 CLDR 语言区域数据以及众多对于 Android 中的国际化支持的增强功能。
新版库包含以下主要变更:
- 许多格式化 API 现在都支持可扩展
FormattedValue
的新返回对象类型。LocaleMatcher
API 在以下方面得到增强:提供了构建器类,支持java.util.Locale
类型,并且结果类可提供有关匹配的额外数据。- 现在支持 Unicode 13。
- 新类:
MediaCodec.LinearBlock
MediaCodec.OutputFrame
MediaCodec.QueueRequest
- 新方法:
MediaCodec.getQueueRequest()
MediaCodec.getOutputFrame()
MediaCodec.LinearBlock.isCodecCopyFreeCompatible()
此外,
MediaCodec.Callback()
中两种方法的行为也发生了变化:
onInputBufferAvailable()
如果配置为使用 Block Model API,应用应通过索引使用 MediaCodec.getQueueRequest,并将 LinearBlock/HardwareBuffer 附加到插槽,而不是通过索引调用 MediaCodec.getInputBuffer() 和 MediaCodec.queueInputBuffer()。onOutputBufferAvailable()
应用可以通过索引使用 MediaCodec.getOutputFrame() 获取包含更多信息的 OutputFrame 对象和 LinearBlock/HardwareBuffer 缓冲区,而不是通过索引调用 MediaCodec.getOutputBuffer()。
MediaCodec
,针对游戏和其他实时应用支持低延时解码。您可以将 FEATURE_LowLatency
传递到 MediaCodecInfo.CodecCapabilities.isFeatureSupported()
,检查编解码器是否支持低延时解码。
- 使用
MediaCodec.configure()
将新键KEY_LOW_LATENCY
设置为 0 或 1。- 使用
MediaCodec.setParameters()
将新参数键PARAMETER_KEY_LOW_LATENCY
设置为 0 或 1。注意:支持低延时解码可能需要额外的资源,例如更高的功耗。仅在必要时使用低延时解码。
新的 AAudio 函数 AAudioStream_release()
函数 AAudioStream_close()
会同时释放和关闭音频流。这可能很危险。如果其他进程在音频流关闭后尝试对其进行访问,该进程将会崩溃。
新函数 AAudioStream_release()
会释放音频流,但不会将其关闭。这样会释放其资源并使音频流处于已知状态。该对象将一直存在,直到您调用 AAudioStream_close()
。
MediaParser API
MediaParser
是用于媒体提取的新型低级别 API。它比 MediaExtractor
更灵活,并提供对媒体提取功能的额外控制。
通过 USB 设备捕获音频
当没有 RECORD_AUDIO
权限的应用使用 UsbManager
请求直接访问具备音频捕获功能的 USB 音频设备(如 USB 耳机)时,系统会显示一条新的警告消息,要求用户确认设备使用权限。系统会忽略任何“始终使用”选项,因此应用每次请求访问时,用户都必须确认警告消息并授予相应权限。
为了避免这种行为,您的应用应请求 RECORD_AUDIO
权限。
注意:此行为
仅适用于使用 UsbManager API 直接连接到 USB 外围设备的应用
。绝大多数媒体播放器、游戏和通信应用使用的是音频 API,因此不会受到此变更的影响。
并发访问麦克风
Android 11 向 AudioRecord
、MediaRecorder
和 AAudioStream
API 添加了一些新方法。不管选择的用例是什么,这些方法均可启用和停用并发捕获的功能。请参阅共享音频输入。
输出切换器
Android 11 针对使用 Cast
和 MediaRouter
API 的应用实现了新行为。
除了可从应用内访问投射选项外,切换选项也显示于系统媒体播放器中。当用户改变视听环境时(例如在厨房中观看视频与在手机上观看之间切换,或者在家中收听音频与在车中收听之间切换),这有助于为用户提供无缝切换设备的流畅体验。请参阅输出切换器。
Wi-Fi Passpoint 增强功能
通过 Passpoint,应用可以自动静默地执行身份验证并连接到安全的 Wi-Fi 热点。以 API 级别 30 及更高级别为目标平台的应用可以使用 Passpoint 的以下其他功能。
- 失效日期强制执行和通知
对个人资料强制执行失效日期可让框架避免使用过期凭据自动连接到接入点,该操作必定会失败。这样可以阻止无线连接,并节省电量和后端带宽。当用户的个人资料位于范围内但已过期时,该功能会向用户显示通知。- FQDN 匹配
允许使用 PerProviderSubscription (PPS) 管理对象 (MO) 中的 Extension/Android 节点,配置独立于接入网络查询协议 (ANQP) 完全限定域名 (FQDN) 的命名 AAA 域。- 自签名的私人 CA
对于 Passpoint R1 个人资料,Android 接受采用私人自签名 CA 进行连接身份验证。- 允许使用具有相同 FQDN 的多个个人资料
允许安装具有相同 FQDN 的多个 Passpoint 个人资料。FQDN 不用作个人资料的键。需要 FQDN 的现有 Passpoint API(如 remove)会将请求应用于具有相同 FQDN 的所有匹配的>- 个人资料。- 允许安装没有根 CA 证书的个人资料
允许使用没有根 CA 证书的个人资料。在这种情况下,系统会根据安装在信任库中的公共根 CA 证书验证 AAA 服务器证书。- 改进了家庭网络服务提供商和漫游服务提供商的匹配
系统会匹配家庭网络或漫游网络,而不考虑所通告的身份验证方法。此外,还增加了对 OtherHomePartners 和 HomeOIList 列表的家庭网络匹配功能的支持。
- 连接管理应用可以通过允许断开连接请求管理自己的网络。
- Passpoint 网络集成到 Suggestion API 中,可以推荐给用户。
- 通过 Analytics API,您可以获取有关网络质量的信息。
CallScreeningService 更新
从 Android 11 开始,CallScreeningService
可以针对来电请求有关 STIR/SHAKEN 验证状态 (verstat) 的信息。此信息将包含在来电的通话详情中。
如果 CallScreeningService
持有 READ_CONTACTS
权限,当用户通讯录中的号码有来电或向用户通讯录中的号码去电时,应用会收到通知。
Open Mobile API 更新
从 Android 11 开始,Open Mobile API (OMAPI) 有了额外的功能:
- 解析运营商权限的规则。
- 使用以下一项或多项自定义嵌入式安全元件 (eSE) 访问权限或配置 eSE:
1、系统特许权限
2、可配置的访问规则应用主数据 (ARA-M) 应用标识符 (AID)
3、用于重置 OMAPI 读取器的系统 API- 为读取器提供清晰的指示符,以便应用过滤设备功能。
高性能 VPN
以 API 级别 30 及更高级别为目标平台的应用或在搭载 API 级别 29 及更高级别的设备上运行的应用可以将 IKEv2/IPsec 应用于 VPN(包括用户配置的 VPN 和基于应用的 VPN)。
VPN 本身在操作系统上运行,从而简化了在应用中建立 IKEv2/IPset VPN 连接所需的代码。
每个进程的网络访问控制
如需了解如何针对各进程启用网络访问权限,请参阅管理网络使用情况。
允许安装的多种 Passpoint
配置具有相同的 FQDN
从 Android 11 开始,您可以使用 PasspointConfiguration.getUniqueId()
获取 PasspointConfiguration
对象的专有标识符,这样可让使用应用的用户安装多个具有相同完全限定域名 (FQDN) 的配置文件。
当运营商在其网络上部署多个移动设备国家/地区代码 (MCC) 和移动网络代码 (MNC) 组合,但只有一个 FQDN 时,此功能非常有用。在 Android 11 及更高版本中,当用户安装具有 MCC 或 MNC 的 SIM 卡时,可以安装多个具有相同 FQDN(它将与家庭网络服务提供商提供的网络匹配)的配置文件。
注意:各配置由唯一键进行标识,该键取决于配置的内容。如需更新现有配置文件,您必须使用
WifiManager.removePasspointConfiguration()
将其移除。如果不移除现有配置,会导致添加一个包含两种配置的新配置文件。
GnssAntennaInfo
类,让您的应用能够更多地利用全球导航卫星系统 (GNSS) 提供的厘米精度定位。如需了解详情,请参阅有关天线校准信息的指南。
ImageDecoder
API 提供了一种标准 API,供 Android C/C++ 应用直接解码图像。应用开发者不再需要使用框架 API(通过 JNI)或捆绑第三方图像解码库。有关详情,请参阅图像解码器开发者指南。Window.setPreferMinimalPostProcessing()
,或将窗口的 preferMinimalPostProcessing
属性设置为 true。并非所有的显示屏都支持最低限度的后期处理;如需了解某个显示屏是否支持该功能,可调用新方法 Display.isMinimalPostProcessingSupported()
。注意:如果用户停用最低限度的后期处理,或者显示屏不支持低延时模式,那么调用
Window.setPreferMinimalPostProcessing()
不会有任何作用。
在主动拍摄期间关闭通知提示音和振动
从 Android 11 开始,在主动使用相机时,您的应用可以使用 setCameraAudioRestriction()
以仅关闭振动、同时关闭声音和振动或都不关闭。
Android 11 添加了 API 以查询对同时使用多个摄像头(包括前置摄像头和后置摄像头)的支持。
如需在运行应用的设备上检查支持情况,请使用以下方法:
getConcurrentCameraIds()
可返回摄像头 ID 组合 Set,这些组合可与有保证的数据流组合并发进行流式传输(如果它们是由同一应用进程配置的)。isConcurrentSessionConfigurationSupported()
可查询摄像头设备是否可以并发支持相应的会话配置。
ImageDecoder.decodeDrawable()
并传递包含帧序列的 HEIF 图片(如动画或连拍照片),则该方法会返回包含整个图片序列的 AnimatedImageDrawable
。在较低版本的 Android 系统中,该方法会返回仅包含单个帧的 BitmapDrawable。如果 HEIF 图片包含的多个帧不在一个序列中,您可以通过调用 MediaMetadataRetriever.getImageAtIndex() 检索各个帧。
面向无障碍服务开发者的更新
如果您创建自定义无障碍服务,可以在 Android 11 中使用以下功能:
在无障碍服务的面向用户的解释中,除了纯文本之外,现在还允许使用 HTML 和图片。这种灵活性可让您更轻松地向最终用户解释您的服务有何功能以及对他们有何帮助。
如需使用比 contentDescription 在语义上更有意义的界面元素的状态说明,请调用 getStateDescription() 方法。
如需请求触摸事件绕过系统的触摸浏览器,请调用 setTouchExplorationPassthroughRegion()。同样,如需请求手势绕过系统的手势检测器,请调用 setGestureDetectionPassthroughRegion()。
您可以请求 IME 操作(如“输入”和“下一个”),以及不启用 FLAG_SECURE 标记的窗口的屏幕截图。
Android Developers:https://developer.android.google.cn/about/versions/11