后台音频强化

从 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

我们进行此次变更的原因

引入这些限制的目的是减少意外的后台音频 bug 体验。部分示例如下:

  • 如果应用在没有前台服务的情况下播放音频,则可能会被冻结。当应用最终解除冻结时,它会意外地恢复音频播放,这可能会在数小时后发生。
  • 在没有前台服务的情况下播放音频的应用会面临各种运行时限制,从而导致音频播放效果不流畅。
  • 播放与 activity 生命周期分离,这可能会导致播放会话或焦点事件泄漏,并且用户无法停止播放。

我们建议开发者测试其应用,并针对任何受到有意音频使用情形负面影响的行为变更提供反馈。 请使用此 Android 17 应用兼容性问题跟踪器报告任何问题。

确定受影响的后台音频使用情形

审核音频播放实现,并确定您的应用是否打算即使在条件性情况下也提供后台音频互动功能。

如果您的应用仅打算在显示用户可见的 activity 时播放音频或利用音频 API,包括使用画中画 (PiP) 模式,则不会受到任何这些更改的影响。

如果您的应用提供 VOIP 功能(包括视频通话应用),那么它必须已经满足针对播放引入的要求(通常是通过利用推荐的 telecom API),才能成功录制音频,因此不太可能受到影响。

如果您的应用打算在屏幕关闭时在 Activity 不可见时继续播放音频(这在在线影音应用或播客应用中最为常见),则您的应用会被视为提供后台音频功能,并且必须满足新要求。

可能会受到影响的后台音频场景

如果您的应用不遵循在应用打开时或响应明确的用户触发器时继续音频互动的模式,则很可能会静默抑制应用的功能。

例如,如果您的应用响应 BOOT_COMPLETE 而启动前台服务并尝试与音频互动,则该应用会被抑制。

可减轻影响的最佳背景音频实践

  • 使用 media3 Jetpack 库的 MediaSessionService 组件来管理后台音频播放。

    如果您这样做,由于该库有助于管理播放生命周期,因此您的应用不太可能受到后台强化功能的影响。

  • 如果您未使用 media3 库,则需要手动启动 mediaPlayback FGS。如果可能会出现后台音频,请务必在应用处于前台时启动前台服务。

    例如,如果您的应用是在线影音应用,通常仅在前台运行,但包含在屏幕关闭时继续播放的用户可供性 (affordance),那么当用户启动播放触发器时,您的应用仍应启动前台服务。

    这样做可确保前台服务以 WIU 功能启动。

  • 在持续时间不到 10 分钟的短暂故障期间,保持 mediaPlayback FGS 处于有效状态。

    如果您的应用出现暂时性故障(例如因网络活动而导致缓冲出现问题),或者出现预期的暂时性中断(例如 AUDIOFOCUS_LOSS_TRANSIENT),则播放意图应继续。因此,您的 FGS 应保持有效状态。

  • 在播放结束时停止前台服务,并且仅在用户明确恢复播放时才重新开始播放。

    如果出现永久性结束播放信号(例如,内容已播放完毕且未自动播放、出现 AUDIOFOCUS_LOSS、来自 UMO 的暂停事件或媒体键事件)或无法恢复的故障,您的应用应停止音频互动、停止前台服务并结束媒体会话。所有这些操作都与用户对“完成”所需后台音频互动的概念相符。完成此操作后,应用将不再具备后台音频互动功能。

    随后,如果用户明确恢复播放(例如通过您的应用界面或通过通用媒体对象播放按钮),则启动音频播放的 intent 应返回,从而导致 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 audiologcat 来确定应用是否因音频安全加固强制执行而遇到静默故障。如果确实如此,则会有一个以 AudioHardening 为前缀的条目,其中包含您的软件包名称。如果消息包含 level: full,则表示您的应用正在运行前台服务,但该服务不具备使用时访问权限。如果消息包含 level: partial,则表示您的应用根本没有运行前台服务。

了解具备使用时权限的 FGS

一般来说,前台服务 (FGS) 必须在应用位于前台时启动,以延长用户发起的运行时间。在某些特定情况下,应用可以在后台运行时启动前台服务。不过,这些前台服务通常不会被授予“使用期间”功能。

WIU 充当安全门,可防止从后台启动的 FGS 在用户可能不知道应用活动的情况下执行某些敏感行为。它会阻止应用访问位置信息、摄像头或麦克风等敏感数据,并且从 Android 17 开始,它还会阻止通常需要可见界面上下文的音频 API。

以下是实用参考信息:

  • 标准 FGS:在应用可见时启动或被授予后台活动启动功能的服务会被授予 WIU 访问权限。
  • 后台启动的 FGS (BFSL):大多数不授予 WIU 访问权限。授予 WIU 的主要例外情况是涉及明确用户意图的互动,例如通知点击、微件互动或来自外部设备的媒体键事件。
  • 系统启动 FGS:如果前台服务是通过系统服务器委托(例如,从 Telecom Jetpack 库)启动的,或者通过表示提升的前台状态的系统绑定来执行专用功能(例如,用于 VoiceInteractionService),则前台服务会被授予 WIU 访问权限。

如需了解详情,请参阅与从后台启动前台服务相关的限制

受影响的音频 API 的完整列表

音频功能

结果

受影响的 API

音频播放

播放已静音

没有任何 API 提供异常或失败消息

AudioTrack.write()

(NDK) AAudioStream_write

面向 Android 的 OpenSL ES

任何管理播放的客户端媒体库(例如 media3、Exoplayer 和 Oboe)也可能会受到影响。

音频焦点请求

返回 AUDIOFOCUS_REQUEST_FAILED

对其他应用的音频播放没有影响,未获取焦点

AudioManager.requestAudioFocus()

音量和响铃模式 API

对铃声模式或音量没有影响(方法调用会被静默忽略)

没有任何 API 提供异常或失败消息

AudioManager.setStreamVolume()

AudioManager.setStreamMute()

AudioManager.adjustStreamVolume()

AudioManager.adjustVolume()

AudioManager.adjustSuggestedStreamVolume()

AudioManager.setRingerMode()