Android 11 面向开发者引入了一些出色的新功能和 API。以下几部分内容可帮助您了解适用于您的应用的功能并开始使用相关 API。
有关新增、修改和移除的 API 的详细列表,请参阅 API 差异报告。如需详细了解新的 API,请访问 Android API 参考文档 - 新 API 会突出显示以方便查看。此外,如需了解平台变更可能会在哪些方面影响您的应用,请务必查看会影响以 Android R 为目标平台的应用和所有应用的 Android 11 行为变更,以及隐私权变更。
新体验
设备控件
Android 11 包含一个新的 ControlsProviderService
API,可用于提供所连接的外部设备的控件。这些控件显示于 Android 电源菜单中的设备控制器下。如需了解详情,请参阅控制外部设备。
媒体控件
Android 11 更新了媒体控件的显示方式。媒体控件显示于快捷设置旁。来自多个应用的会话排列在一个可滑动的轮播界面中,其中包括在手机本地播放的会话流、远程会话流(例如在外部设备上检测到的会话或投射会话)以及可继续播放的以前的会话(按上次播放的顺序排列)。
用户无需启动相关应用即可在轮播界面中重新开始播放以前的会话。当播放开始后,用户可按常规方式与媒体控件互动。
如需了解详情,请参阅媒体控件。
屏幕
更好地支持瀑布屏
Android 11 提供了一些 API 以支持瀑布屏,这是一种无边框的全面屏。这种显示屏被视为刘海屏的变体。现有的 DisplayCutout
.getSafeInset…()
方法现在会返回能够避开瀑布区域以及刘海的安全边衬区。如需在瀑布区域中呈现您的应用内容,请执行以下操作:
调用
DisplayCutout.getWaterfallInsets()
以获取瀑布边衬区的精确尺寸。将窗口布局属性
layoutInDisplayCutoutMode
设为LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
,以允许窗口延伸到屏幕各个边缘上的刘海和瀑布区域。您必须确保刘海或瀑布区域中没有重要的内容。
铰链角度传感器和可折叠设备
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()
创建气泡图标。
5G 图标显示
如需了解如何在用户的设备上显示 5G 图标,请参阅在用户连接到 5G 网络时显示相关信息。
隐私设置
Android 11 引入了大量变更和限制,目的是加强用户隐私保护。如需了解详情,请参阅隐私权页面。
安全
生物识别身份验证机制更新
为了帮助您控制应用数据的安全级别,Android 11 对生物识别身份验证机制进行了多项改进。这些变更也会在 Jetpack Biometric 库中显示。
身份验证类型
Android 11 引入了 BiometricManager.Authenticators
接口,可用于声明您的应用支持的身份验证类型。
确定用户所用的身份验证类型
在用户进行身份验证后,您可以通过调用 getAuthenticationType()
检查用户是使用设备凭据还是生物识别凭据进行的身份验证。
对“每次使用时进行身份验证”密钥的额外支持
Android 11 提供了对“每次使用时进行身份验证”密钥的更多支持。
已弃用的方法
Android 11 弃用了以下方法:
setDeviceCredentialAllowed()
方法。setUserAuthenticationValidityDurationSeconds()
方法。- 不带任何参数的
canAuthenticate()
过载版本。
安全共享大型数据集
在某些情况下,例如涉及机器学习或媒体播放时,您的应用可能需要与其他应用使用同一个大型数据集。在较早的 Android 版本中,您的应用与其他应用需要各自单独下载该数据集。
为帮助减少网络中和磁盘上的数据冗余,Android 11 允许使用共享数据 blob 在设备上缓存这些大型数据集。如需详细了解如何共享数据集,请参阅有关共享大型数据集的深度指南。
因 OTA 更新而重启设备后在未提供用户凭据的情况下执行文件级加密
设备完成 OTA 更新并重启后,放在受凭据保护的存储空间中的凭据加密 (CE) 密钥可立即用于执行文件级加密 (FBE) 操作。这意味着,完成 OTA 更新后,您的应用可以在用户输入其 PIN 码、解锁图案或密码之前恢复需要 CE 密钥的操作。
性能和质量
无线调试
Android 11 支持通过 Android 调试桥 (adb) 从工作站以无线方式部署和调试应用。例如,您可以将可调试的应用部署到多台远程设备,而无需通过 USB 实际连接您的设备,从而避免常见的 USB 连接问题(例如驱动程序安装方面的问题)。如需了解详情,请参阅在硬件设备上运行应用。
ADB 增量 APK 安装
在设备上安装大型(2GB 以上)APK 可能需要很长的时间,即使应用只是稍作更改也是如此。ADB(Android 调试桥)增量 APK 安装可以安装足够的 APK 以启动应用,同时在后台流式传输剩余数据,从而加速这一过程。如果设备支持该功能,并且您安装了最新的 SDK 平台工具,adb install
将自动使用此功能。如果不支持,系统会自动使用默认安装方法。
运行以下 adb 命令以使用该功能。如果设备不支持增量安装,该命令将会失败并输出详细的解释。
adb install --incremental
在运行 ADB 增量 APK 安装之前,您必须先为 APK 签名并创建一个 APK 签名方案 v4 文件。必须将 v4 签名文件放在 APK 旁边,才能使此功能正常运行。
使用原生内存分配器进行错误检测
GWP-ASan 是一种原生内存分配器功能,可帮助查找释放后使用和堆缓冲区溢出错误。您可以全局启用此功能,也可以为应用的特定子进程启用此功能。如需了解详情,请参阅 GWP-Asan 指南。
Neural Networks API 1.3
Android 11 扩展并改进了 Neural Networks API (NNAPI)。
新运算方式
NNAPI 1.3 引入了新的运算数类型 TENSOR_QUANT8_ASYMM_SIGNED
,以支持 TensorFlow Lite 的新量化方案。
此外,NNAPI 1.3 还引入了以下新运算:
QUANTIZED_LSTM
IF
WHILE
ELU
HARD_SWISH
FILL
RANK
新的机器学习控件
NNAPI 1.3 引入了新控件以帮助机器学习流畅运行:
QoS API:新的 Quality of Service API 使用以下新函数,支持在 NNAPI 中进行优先排序和任务截止时间设定:
内存域输入/输出:NNAPI 1.3 支持将内存域作为执行的输入和输出。这样可以移除不同系统组件之间不必要的相同数据,从而提高 Android 神经网络的运行时性能。此功能添加了一组用于与
ANeuralNetworksMemoryDesc
和ANeuralNetworkMemory
对象结合使用的新 NDK API,包括以下函数:ANeuralNetworksMemoryDesc_create()
ANeuralNetworksMemoryDesc_free()
ANeuralNetworksMemoryDesc_addInputRole()
ANeuralNetworksMemoryDesc_addOutputRole()
ANeuralNetworksMemoryDesc_setDimensions()
ANeuralNetworksMemoryDesc_finish()
ANeuralNetworksMemory_createFromDesc()
ANeuralNetworksMemory_copy()
如需了解详情,请参阅神经网络内存域示例。
Dependency API 和同步栅栏支持:NNAPI 1.3 支持使用依赖项实现异步计算,这样可以大大减少调用小型链式模型时产生的开销。此功能添加了以下新函数:
控制流:NNAPI 1.3 支持使用新的图表运算
ANEURALNETWORKS_IF
和ANEURALNETWORKS_WHILE
实现常规控制流,这些运算使用新的ANEURALNETWORKS_MODEL
运算数类型接受其他模型作为参数。此外,此功能还添加了以下新函数:
NDK Thermal API
当设备过热时,它们可能会限制 CPU 和/或 GPU,而这可能会以意想不到的方式影响应用。如果应用或游戏包含复杂图形,大量计算或持续网络活动,它们就更容易遇到问题。
在 Android 11 中使用 NDK Thermal API 监控设备上的温度变化,然后采取相应措施以降低耗电量和设备温度。该 API 类似于Java Thermal API;您可以使用它接收任何热状态更改的通知或直接轮询当前状态。
文本和输入
改进了 IME 转换
Android 11 引入了新的 API 以改进输入法 (IME) 的转换,例如屏幕键盘。这些 API 可让您更轻松地调整应用内容,与 IME 的出现和消失以及状态和导航栏等其他元素保持同步。
如需在聚焦至任何 EditText
时显示 IME,请调用 view.getInsetsController().show(Type.ime())
(您可以在与聚焦的 EditText
相同层次结构中的任何视图上调用此方法,无需专门在 EditText
上调用它)。如需隐藏 IME,请调用 view.getInsetsController().hide(Type.ime())
。您可以通过调用 view.getRootWindowInsets().isVisible(Type.ime())
检查 IME 当前是否可见。
如需同步应用的视图与 IME 的显示和消失,请通过提供 WindowInsetsAnimation.Callback
到 View.setWindowInsetsAnimationCallback()
在视图上设置监听器(您可以在任何视图上设置该监听器,它不一定必须为 EditText
)。IME 会调用监听器的 onPrepare()
方法,之后会在转换开始时调用 onStart()
。然后,它会在每次转换的过程中调用 onProgress()
。转换完成后,IME 会调用 onEnd()
。在转换过程中,您随时可以调用 WindowInsetsAnimation.getFraction()
以了解转换的进度。
有关如何使用这些 API 的示例,请参阅新的 WindowInsetsAnimation 代码示例。
控制 IME 动画
您还可以控制 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) // 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. 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() {} });
ICU 库更新
Android 11 更新了 android.icu
软件包,以使用 ICU 库版本 66,而 Android 10 中使用的是版本 63。新版库包含更新的 CLDR 语言区域数据以及众多对于 Android 中的国际化支持的增强功能。
新版库包含以下主要变更:
- 许多格式化 API 现在都支持可扩展
FormattedValue
的新返回对象类型。 LocaleMatcher
API 在以下方面得到增强:提供了构建器类,支持java.util.Locale
类型,并且结果类可提供有关匹配的额外数据。- 现在支持 Unicode 13。
媒体
分配 MediaCodec 缓冲区
Android 11 包含一个新的 MediaCodec
API,可让应用在分配输入和输出缓冲区时获得更多控制。这样可以让您的应用更高效地管理内存。
新类:
新方法:
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 低延时解码
Android 11 增强了 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
权限。
并发访问麦克风
Android 11 向 AudioRecord
、MediaRecorder
和 AAudioStream
API 添加了一些新方法。不管选择的用例是什么,这些方法均可启用和停用并发捕获的功能。请参阅共享音频输入。
输出切换器
Android 11 针对使用 Cast 和 MediaRouter API 的应用实现了新行为。
除了可从应用内访问投射选项外,切换选项也显示于系统媒体播放器中。当用户改变视听环境时(例如在厨房中观看视频与在手机上观看之间切换,或者在家中收听音频与在车中收听之间切换),这有助于为用户提供无缝切换设备的流畅体验。请参阅输出切换器。
网络连接
WLAN Passpoint 增强功能
如需了解 Android 11 中添加的 Passpoint 功能,请参阅 Passpoint。
Wi-Fi Suggestion API 扩展
Android 11 扩展了 Wi-Fi Suggestion API,以提高应用的网络管理能力,包括:
- 连接管理应用可以通过允许断开连接请求管理自己的网络。
- Passpoint 网络集成到 Suggestion API 中,可以推荐给用户。
- 通过 Analytics API,您可以获取有关网络质量的信息。
CallScreeningService 更新
从 Android 11 开始,CallScreeningService 可以针对来电请求有关 STIR/SHAKEN 验证状态 (verstat) 的信息。此信息将包含在来电的通话详情中。
如果 CallScreeningService
持有 READ_CONTACTS
权限,当用户通讯录中的号码有来电或向用户通讯录中的号码去电时,应用会收到通知。
如需了解详情,请参阅防范来电显示欺骗。
Open Mobile API 更新
如需了解 Android 11 及更高版本中的 OMAPI 支持,请参阅 Open Mobile API 读取器支持。
高性能 VPN
以 API 级别 30 及更高级别为目标平台的应用或在搭载 API 级别 29 及更高级别的设备上运行的应用可以将 IKEv2/IPsec 应用于 VPN(包括用户配置的 VPN 和基于应用的 VPN)。
VPN 本身在操作系统上运行,从而简化了在应用中建立 IKEv2/IPsec VPN 连接所需的代码。
每个进程的网络访问控制
如需了解如何针对各进程启用网络访问权限,请参阅管理网络使用情况。
允许安装的多种 Passpoint 配置具有相同的 FQDN
从 Android 11 开始,您可以使用 PasspointConfiguration.getUniqueId()
获取 PasspointConfiguration
对象的专有标识符,这样可让使用应用的用户安装多个具有相同完全限定域名 (FQDN) 的配置文件。
当运营商在其网络上部署多个移动设备国家/地区代码 (MCC) 和移动网络代码 (MNC) 组合,但只有一个 FQDN 时,此功能非常有用。在 Android 11 及更高版本中,当用户安装具有 MCC 或 MNC 的 SIM 卡时,可以安装多个具有相同 FQDN(它将与家庭网络服务提供商提供的网络匹配)的配置文件。
GNSS 天线支持
Android 11 引入了 GnssAntennaInfo
类,让您的应用能够更多地利用全球导航卫星系统 (GNSS) 提供的厘米精度定位。
如需了解详情,请参阅有关天线校准信息的指南。
图形
NDK 图像解码器
NDK ImageDecoder
API 提供了一种标准 API,供 Android C/C++ 应用直接解码图像。应用开发者不再需要使用框架 API(通过 JNI)或捆绑第三方图像解码库。有关详情,请参阅图像解码器开发者指南。
Frame rate API
Android 11 提供了一个 API,可让应用告知系统其预期帧速率,从而减少支持多个刷新率的设备上的抖动。有关如何使用此 API 的信息,请参阅帧速率指南。
请求并检查低延时支持
特定的显示屏可以执行图形后期处理,例如某些外部显示屏和电视。此类后期处理改善了图形质量,但可能会增加延时。支持 HDMI 2.1 的新款显示屏具有自动低延时模式(ALLM,也称为游戏模式),该模式可以通过关闭后期处理以最大限度地缩短延时。如需详细了解 ALLM,请参阅 HDMI 2.1 规范。
窗口可以请求使用自动低延时模式(如果可用)。ALLM 对于游戏和视频会议等应用特别有用,因为对于这些应用而言,低延时的重要性要高于拥有最佳的图形质量。
如需开启或关闭最低限度的后期处理,请调用 Window.setPreferMinimalPostProcessing()
,或将窗口的 preferMinimalPostProcessing
属性设置为 true
。并非所有的显示屏都支持最低限度的后期处理;如需了解某个显示屏是否支持该功能,可调用新方法 Display.isMinimalPostProcessingSupported()
。
高性能图形调试层注入
应用现在可以将外部图形层(GLES、Vulkan)加载到原生应用代码中,可以在不产生性能开销的前提下,提供与可调试应用相同的功能。在使用 GAPID 等工具对应用进行性能剖析时,此功能尤为重要。如需对应用进行性能剖析,只需要在应用清单文件中添加以下元数据元素,而无需让应用变成可调试应用:
<application ... > <meta-data android:name="com.android.graphics.injectLayers.enable" android:value="true" /> </application>
图片和相机
在主动拍摄期间关闭通知提示音和振动
从 Android 11 开始,在主动使用相机时,您的应用可以使用 setCameraAudioRestriction()
以仅关闭振动、同时关闭声音和振动或都不关闭。
Android 模拟器中的相机支持扩展
如需了解自 Android 11 起模拟器中的相机支持扩展,请参阅相机支持。
支持并发使用多个摄像头
Android 11 添加了 API 以查询对同时使用多个摄像头(包括前置摄像头和后置摄像头)的支持。
如需在运行应用的设备上检查支持情况,请使用以下方法:
getConcurrentCameraIds()
可返回摄像头 ID 组合Set
,这些组合可与有保证的数据流组合并发进行流式传输(如果它们是由同一应用进程配置的)。isConcurrentSessionConfigurationSupported()
可查询摄像头设备是否可以并发支持相应的会话配置。
更好地支持包含多个帧的 HEIF 图片
从 Android 11 开始,如果您调用 ImageDecoder.decodeDrawable()
并传递包含帧序列的 HEIF 图片(如动画或连拍照片),则该方法会返回包含整个图片序列的 AnimatedImageDrawable
。在较低版本的 Android 系统中,该方法会返回仅包含单个帧的 BitmapDrawable
。
如果 HEIF 图片包含的多个帧不在一个序列中,您可以通过调用 MediaMetadataRetriever.getImageAtIndex()
检索各个帧。
无障碍功能
面向无障碍服务开发者的更新
如果您创建自定义无障碍服务,可以在 Android 11 中使用以下功能:
- 在无障碍服务的面向用户的解释中,除了纯文本之外,现在还允许使用 HTML 和图片。这种灵活性可让您更轻松地向最终用户解释您的服务有何功能以及对他们有何帮助。
- 如需使用比
contentDescription
在语义上更有意义的界面元素的状态说明,请调用getStateDescription()
方法。 - 如需请求触摸事件绕过系统的触摸浏览器,请调用
setTouchExplorationPassthroughRegion()
。同样,如需请求手势绕过系统的手势检测器,请调用setGestureDetectionPassthroughRegion()
。 - 您可以请求 IME 操作(如“输入”和“下一个”),以及不启用
FLAG_SECURE
标记的窗口的屏幕截图。
其他功能
应用进程退出原因
Android 11 引入了 ActivityManager.getHistoricalProcessExitReasons()
方法,用于报告近期任何进程终止的原因。应用可以使用此方法收集崩溃诊断信息,例如进程终止是由于 ANR、内存问题还是其他原因所致。此外,您还可以使用新的 setProcessStateSummary()
方法存储自定义状态信息,以便日后进行分析。
getHistoricalProcessExitReasons()
方法会返回 ApplicationExitInfo
类的实例,该类包含与应用进程终止相关的信息。通过对此类的实例调用 getReason()
,您可以确定应用进程终止的原因。例如,返回值为 REASON_CRASH
表示您的应用中发生了未处理的异常。如果您的应用需要确保退出事件的唯一性,它可以维护一个应用专用的标识符,如基于来自 getTimestamp()
方法的时间戳的哈希值。
其他资源
如需了解详情,请参阅 Medium 上介绍可提高应用隐私性和稳定性的新 Android 11 工具的文章。
资源加载器
Android 11 引入了一个新 API,允许应用动态扩展资源的搜索和加载方式。新的 API 类 ResourcesLoader
和 ResourcesProvider
主要负责提供新功能。两者协同作用,可以提供额外的资源,或修改现有资源的值。
ResourcesLoader
对象是向应用的 Resources
实例提供 ResourcesProvider
对象的容器,而 ResourcesProvider
对象提供从 APK 和资源表加载资源数据的方法。
此 API 的一个主要用例是自定义资源加载。您可以使用 loadFromDirectory()
创建一个 ResourcesProvider
,用于重定向基于文件的资源的解析,从而让其搜索特定目录,而不是应用 APK。您可以通过 AssetManager
API 类中的 open()
系列方法访问这些资源,就像访问 APK 中绑定的资源一样。
APK 签名方案 v4
Android 11 添加了对 APK 签名方案 v4 的支持。此方案会在单独的文件 (apk-name.apk.idsig
) 中生成一种新的签名,但在其他方面与 v2 和 v3 类似。没有对 APK 进行任何更改。此方案支持 ADB 增量 APK 安装,这样会加快 APK 安装速度。
动态 intent 过滤器
如需接收 intent,应用必须通过在其清单中定义 intent 过滤器,在编译时声明它能够接收哪些类型的数据。在 Android 10 及更低版本中,应用无法在运行时更改其 intent 过滤器。这对于虚拟化应用(如虚拟机和远程桌面)而言是一个问题,因为这些应用无法确切得知用户将在它们内部安装什么软件。
Android 11 引入了 MIME 组,这是一个新的清单元素,可让应用在 intent 过滤器中声明一组动态的 MIME 类型,并在运行时以编程方式对其进行修改。如需使用 MIME 组,请使用新的 android:mimeGroup
属性在应用清单中添加一个数据元素:
<intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeGroup="myMimeGroup"/> </intent-filter>
android:mimeGroup
属性的值是任意字符串 ID,用于在运行时标识 MIME 组。您可以通过将某个 MIME 组的 ID 传递给 PackageManager
API 类中的以下新方法,访问和更新该 MIME 组的内容:
如果您以编程方式将 MIME 类型添加到 MIME 组,其运作方式与清单中明确声明的静态 MIME 类型完全相同。
自动填充增强功能
Android 11 改进了自动填充服务。
AssistStructure.ViewNode 中的提示标识符
对自动填充服务来说,根据视图的属性计算视图的签名哈希值通常很有用。在计算签名哈希值时,视图提示是一个非常值得参考的属性,但提示字符串可能会随着手机的语言区域而发生变化。为了解决此问题,Android 11 使用新的 getHintIdEntry()
方法扩展了 AssistStructure.ViewNode
,该方法会返回视图提示文本的资源标识符。此方法提供一个与语言区域无关的值,可用于计算签名哈希值。
提供了数据集的事件
为了帮助自动填充服务提高建议内容的质量,Android 11 提供了一种方法以识别自动填充服务提供了数据集但用户未选择任何数据集的情况。在 Android 11 中,FillEventHistory
会报告一种新的 TYPE_DATASETS_SHOWN
事件类型。每当自动填充服务向用户提供一个或多个数据集时,FillEventHistory
就会记录此类型的事件。自动填充服务可以将这些事件与现有的 TYPE_DATASET_SELECTED
事件结合使用来确定用户是否选择了任何提供的自动填充选项。
IME 集成
键盘及其他 IME 现在可以在建议栏或类似的界面中以内嵌方式显示自动填充建议,而不是在下拉菜单中显示这些建议。为了保护密码和信用卡号等敏感信息,系统会将建议显示给用户,但在用户选择某条建议之前,IME 并不知道这些建议。如需了解 IME 和密码管理器如何支持此功能,请参阅将自动填充功能与键盘集成。
与内容捕获服务共享数据
从 Android 11 开始,应用可以与设备的内容捕获服务共享数据。借助此功能,设备可以更轻松地提供情境智能,例如显示用户环境中正在播放的歌曲的名称。
如需将应用中的数据共享给内容捕获服务,请对 ContentCaptureManager
的实例调用 shareData()
方法。如果系统接受数据共享请求,应用会收到将与内容捕获服务共享的只写文件描述符。