从 Android 17 开始,音频框架会对后台音频互动(包括音频播放、音频焦点请求和音量更改 API)强制执行限制,以确保这些更改是由用户有意启动的。
在 Android 17 上运行的所有具有这些后台音频互动的应用都必须具有可见的 activity,或者必须运行类型不是 SHORT_SERVICE 的前台服务。无论应用是否以 API 级别 37 为目标平台,此要求都适用。
如果应用以 Android 17(API 级别 37)为目标平台,则存在额外的限制。如果应用在后台运行,则应用必须运行具有 使用期间 (WIU) 功能的
前台服务。(如果前台服务是响应用户启动的操作而启动的,或者在应用对用户可见时启动的,则该前台服务会被授予 WIU 功能。) 不过,如果应用已被授予
精确闹钟权限,并且正在更改具有
USAGE_ALARM属性的音频流,则可以免除对 WIU 功能的要求。
如果应用尝试在应用处于无效生命周期时调用音频 API,则音频播放和音量更改 API 会静默失败,而不会抛出异常或提供失败消息。音频焦点 API 会失败,并返回结果代码 AUDIOFOCUS_REQUEST_FAILED。
我们做出此变更的原因
引入这些限制的目的是减少意外的后台音频错误体验。部分示例如下:
- 在没有前台服务的情况下播放音频的应用可能会被冻结。当应用最终被解冻时,它会意外地恢复音频播放,这可能会在数小时后发生。
- 在没有前台服务的情况下播放音频的应用面临各种运行限制,这会导致音频性能不流畅。
- 播放与 activity 生命周期分离,这可能会导致播放会话泄露或焦点事件泄露,并且用户无法停止播放。
我们鼓励开发者测试其应用,并针对任何受到负面影响的有意音频用例提供有关行为变更的反馈。 请使用此 Android 17 应用兼容性问题 跟踪器报告任何问题。
确定受影响的后台音频用例
审核您的音频播放实现,并确定您的应用是否打算在条件情况下也提供后台音频互动功能。
如果您的应用仅打算在显示 对用户可见的 activity(包括使用 画中画 (PiP) 模式)时播放音频或使用音频 API,则不会受到任何这些变更的影响。
如果您的应用提供 VOIP 功能(包括视频通话应用),则它 必须已满足为播放引入的要求(通常 通过使用推荐的 电信 API)才能成功录制 音频,因此不太可能受到影响。
如果您的应用打算在屏幕关闭时 或 您的 Activity 不可见时继续播放音频(这在在线影音应用或播客应用中最为常见),则您的应用会被视为提供后台音频功能,并且必须满足新要求。
可能会受到影响的后台音频场景
如果您的应用不遵循在应用打开时或响应显式用户触发器时继续音频互动这一模式,则应用的功能可能会被静默抑制。
例如,如果您的应用响应 BOOT_COMPLETE 而启动前台服务并尝试与音频互动,则会被抑制。
降低影响的最佳后台音频实践
使用 media3 Jetpack 库的
MediaSessionService组件来 管理后台音频播放。如果您这样做,您的应用不太可能受到后台安全加固措施的影响,因为该库有助于管理播放生命周期。
如果您未使用 media3 库,则需要手动启动
mediaPlaybackFGS。如果可能会发生后台音频,请始终在应用处于前台时启动前台服务。例如,如果您的应用是在线影音应用,该应用通常仅在前台运行,但包含一个用户功能,可在屏幕关闭时继续播放,那么当用户启动播放触发器时,您的应用仍应启动前台服务。
这样做可确保前台服务以 WIU 功能启动。
在 10 分钟以内的暂时性故障期间,保持
mediaPlaybackFGS 处于活动状态。如果您的应用出现暂时性故障(例如因网络活动而导致缓冲出现问题),或者出现预期的暂时性中断(例如
AUDIOFOCUS_LOSS_TRANSIENT),则播放意图应继续。因此,您的 FGS 应保持活动状态。在播放结束时停止前台服务,并且仅在用户明确恢复播放时才重新启动播放。
如果出现永久性信号来结束播放(例如,内容已完成且没有自动播放、
AUDIOFOCUS_LOSS、来自 UMO 的暂停事件或媒体关键事件)或无法恢复的故障,您的应用应停止音频互动、停止前台服务并结束媒体会话。所有这些操作都符合用户对“完成”所需后台音频互动的概念。完成此操作后,您的应用不再具有后台音频互动功能。随后,如果用户明确恢复播放(例如通过您的应用界面或通过通用媒体对象播放按钮),则启动音频播放的意图应返回,从而导致新启动的 FGS。
使用 adb shell 命令测试音频播放行为。
测试变更
您可以通过运行以下 ADB 命令,在运行 Android 17 或更高版本(从 Beta 3 开始)的应用上测试应用的合规性:
adb shell cmd audio set-enable-hardening <enable|disable|throw>
此命令具有以下选项:
enable:为所有应用启用所有音频强化限制。无论应用是否以 Android 17(API 级别 37)为目标平台,都适用对 WIU 前台服务的要求。此外,即使应用正在更改闹钟流并具有精确闹钟权限,也会强制执行该要求。disable:停用所有音频强化限制。throw:为所有应用启用所有音频安全加固限制,如enable。此外,此标志还会启用响亮的失败,针对音量和焦点互动抛出IllegalStateException。对于音频播放,写入方法会持续返回错误代码。对于没有显式写入的播放模式,应用会崩溃。
使用 adb dumpsys audio 或 logcat 确定应用是否因音频安全加固强制执行而遇到静默失败。如果是,则会有一个以 AudioHardening 为前缀的条目,其中包含您的软件包名称。如果消息包含 level: full,则表示您的应用正在运行前台服务,但该服务不具备使用期间功能。如果消息包含 level: partial,则表示您的应用根本没有运行前台服务。
了解具有使用期间功能的前台服务
一般来说,前台服务 (FGS) 必须在应用处于前台时启动,以扩展用户启动的操作。在某些特定情况下, 应用可以在后台运行时启动前台服务。不过,这些前台服务通常不会被授予使用期间 (WIU) 功能。
WIU 充当安全门,可防止从后台启动的 FGS 在用户可能不知道应用活动的情况下执行某些敏感行为。它可以防止应用访问敏感数据(如位置信息、摄像头或麦克风),并且从 Android 17 开始,它还会屏蔽通常需要可见界面上下文的音频 API。
以下是一些实用参考资料:
- 标准 FGS:在应用可见或被授予 后台 activity 启动功能时启动的服务会被授予 WIU 访问权限。
- 后台启动的 FGS (BFSL):大多数不会授予 WIU 访问权限。授予 WIU 的 主要 例外情况是涉及显式用户 意图的互动,例如通知点击、微件互动或来自外部设备的媒体键 事件。
- 系统启动的 FGS:如果前台服务是由系统服务器委托(例如来自 Telecom Jetpack 库)或由表示提升的前台状态的系统绑定启动以执行专用功能(例如针对
VoiceInteractionService),则会被授予 WIU 访问权限。
如需了解详情,请参阅与从后台启动前台服务相关的限制。
受影响的音频 API 的完整列表
音频功能 |
结果 |
受影响的 API |
音频播放 |
播放静音 没有任何例外情况,任何 API 均未提供失败消息 |
(NDK) 管理播放的任何客户端媒体库(例如 media3、Exoplayer 和 Oboe)也可能会受到影响。 |
音频焦点请求 |
返回 对其他应用的音频播放没有影响,没有获取焦点 |
|
音量和响铃模式 API |
对响铃模式或音量没有影响(方法调用会被静默忽略) 没有任何例外情况,任何 API 均未提供失败消息 |
|