后台音频强化

从 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 库,则需要手动启动 mediaPlayback FGS。如果可能发生后台音频播放,请始终在应用处于前台时启动前台服务。

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

    这样做可确保前台服务在启动时具有 WIU 功能。

  • 在持续时间不到 10 分钟的暂时性故障期间,让 mediaPlayback FGS 保持活跃状态。

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

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

    如果收到永久结束播放的信号(例如,内容播放完毕且未设置自动播放、收到 AUDIOFOCUS_LOSS、收到 UMO 发出的暂停事件或收到媒体键事件)或发生不可恢复的故障,您的应用应停止音频互动、停止前台服务并结束媒体会话。完成所有这些操作即表示用户已“完成”所需的后台音频互动。完成此操作后,您的应用将不再具有后台音频互动功能。

    随后,如果用户明确恢复播放(例如通过应用的界面或通用媒体对象播放按钮),则启动音频播放的 intent 应返回,从而启动新的 FGS。

  • 使用 adb shell 命令测试音频播放行为。

测试变更

您可以在搭载 Android 17 或更高版本(从 Beta 版 3 开始)的应用上运行以下 ADB 命令,测试应用是否符合要求:

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 充当安全门,可防止从后台启动的前台服务在用户可能未察觉到应用活动的情况下执行某些敏感行为。它会阻止应用访问敏感数据(例如位置信息、相机或麦克风),并且从 Android 17 开始,它还会阻止通常需要可见界面上下文的音频 API。

以下是便捷参考:

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

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

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

音频功能

结果

受影响的 API

音频播放

播放已静音

任何 API 均未提供异常或失败消息

AudioTrack.write()

(NDK) AAudioStream_write

OpenSL ES for Android

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

音频焦点请求

返回 AUDIOFOCUS_REQUEST_FAILED

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

AudioManager.requestAudioFocus()

音量和响铃模式 API

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

任何 API 均未提供异常或失败消息

AudioManager.setStreamVolume()

AudioManager.setStreamMute()

AudioManager.adjustStreamVolume()

AudioManager.adjustVolume()

AudioManager.adjustSuggestedStreamVolume()

AudioManager.setRingerMode()