強化背景音訊

從 Android 17 開始,音訊架構會對背景音訊互動施加限制,包括音訊播放、音訊焦點要求和音量變更 API,確保這些變更是由使用者刻意啟動。

如果應用程式開發人員打算在沒有可見活動的情況下控制音訊,應確保應用程式具有以「使用中」 (WIU) 功能啟動的前景服務 (不是 SHORT_SERVICE 類型)。如果前景服務是因應 MediaSessionEvent 啟動,或是在應用程式向使用者顯示時啟動,系統就會授予該服務 WIU 功能。

如果應用程式嘗試在無效的生命週期呼叫音訊 API,音訊播放和音量變更 API 會無聲無息地失敗,不會擲回例外狀況或提供失敗訊息。音訊焦點 API 失敗,結果代碼為 AUDIOFOCUS_REQUEST_FAILED

我們推出這些限制,是為了減少無意間的背景音訊錯誤體驗。例如:

  • 如果應用程式在沒有前景服務的情況下播放音訊,可能會遭到凍結。應用程式最終解除凍結時,可能會在數小時後意外繼續播放音訊。
  • 如果應用程式未透過前景服務播放音訊,就會面臨各種執行限制,導致音訊播放不流暢。
  • 播放作業與活動生命週期分離,可能導致播放工作階段或焦點事件洩漏,且使用者無法停止播放。

如果任何有意使用的音訊用途受到負面影響,我們鼓勵開發人員測試應用程式並提供意見回饋,協助我們因應行為變化做出調整。如果發現任何問題,請使用這個 Android 17 應用程式相容性問題追蹤工具回報。

找出受影響的背景音訊用途

稽核音訊播放實作項目,並確認應用程式是否打算在條件式情況下,提供背景音訊互動功能。

如果應用程式只會在向使用者顯示活動時播放音訊或使用音訊 API,包括使用子母畫面 (PiP) 模式,就不會受到這些異動影響。

如果您的應用程式提供 VoIP 功能 (包括視訊通話應用程式),就必須符合播放功能的新規定 (通常是使用建議的 電信 API),才能順利錄製音訊,因此不太可能受到影響。

如果應用程式打算在螢幕關閉或使用者完全關閉活動時繼續播放音訊 (音樂串流應用程式或 Podcast 應用程式最常見這種情況),則應用程式會被視為提供背景音訊功能,因此必須符合新規定。

可能受到影響的背景音訊情境

如果應用程式未遵循相關模型,在開啟應用程式或回應使用者明確觸發動作時,繼續進行音訊互動,應用程式功能很可能會遭到無聲抑制。

舉例來說,如果應用程式啟動前景服務來回應 BOOT_COMPLETE,並嘗試與音訊互動,系統就會抑制這項操作。

降低背景音訊影響的最佳做法

  • 使用 media3 Jetpack 程式庫的 MediaSessionService 元件,管理背景音訊播放作業。

    這樣一來,由於程式庫會協助管理播放生命週期,您的應用程式就不太可能受到背景強化措施影響。

  • 如果沒有使用 media3 程式庫,您必須手動啟動 mediaPlayback FGS。如果可能發生背景音訊,請務必在應用程式位於前景時啟動前景服務。

    舉例來說,如果您的應用程式是影片串流應用程式 (通常只會在前景執行),但包含使用者可繼續播放影片的介面 (即使螢幕關閉也一樣),那麼當使用者啟動播放觸發程序時,應用程式仍應啟動前景服務。

    這樣做可確保前景服務啟動時具備 WIU 功能。

  • 如果暫時性故障時間不超過 10 分鐘,請保持 mediaPlayback FGS 運作。

    如果應用程式發生暫時性故障 (例如因網路活動導致緩衝處理問題),或是預期會發生暫時性中斷 (例如 AUDIOFOCUS_LOSS_TRANSIENT),則應繼續播放。因此 FGS 應保持有效。

  • 在播放結束時停止前景服務,且只有在使用者明確恢復播放時才重新啟動播放。

    如果收到永久終止播放的信號 (例如內容已播放完畢且未自動播放、收到 AUDIOFOCUS_LOSS、UMO 傳送的暫停事件,或是媒體鍵事件),或是發生無法復原的錯誤,應用程式應停止音訊互動、停止前景服務,並結束媒體工作階段。使用者會將上述所有操作視為「完成」所需的背景音訊互動。完成後,應用程式就不再具備背景音訊互動功能。

    隨後,如果使用者明確繼續播放 (例如透過應用程式的 UI 或通用媒體物件的播放按鈕),啟動音訊播放的意圖應會傳回,導致 FGS 重新啟動。

  • 使用 adb shell 指令測試音訊播放行為。

測試 Android 16 和 Android 17 的變更

Android 16 以上版本已在「警告」層級實作這項功能。也就是說,應用程式可以使用 adb shell cmd audio set-enable-hardening 手動測試背景音訊強化措施的強制執行情況。

如要在執行 Android 16 的裝置上啟用強制執行功能,請執行下列指令:

adb shell cmd audio set-enable-hardening 1

如要在搭載 Android 17 的裝置上停用強制執行功能,請執行下列指令:

adb shell cmd audio set-enable-hardening 0

此外,我們也建議使用 logcat 或 adb 指令 adb dumpsys audio,判斷應用程式是否因強制執行音訊強化措施而發生無聲失敗。如果有的話,記錄檔會包含以 AudioHardening 為前置字元的項目,並附上您的套件名稱。

瞭解具備「使用中」功能的 FGS

一般來說,應用程式必須處於前景狀態,才能啟動前景服務 (FGS) 來延長使用者啟動的操作。在某些特定情況下,應用程式在背景執行時可以啟動前景服務。不過,這些前景服務通常不會獲得「使用中」權限。

WIU 可做為安全閘道,防止從背景啟動的前景服務在使用者可能不知道應用程式活動的情況下,從事特定敏感行為。這項功能可防止應用程式存取位置、相機或麥克風等私密資料,並從 Android 17 開始封鎖通常需要可見 UI 環境的音訊 API。

請參考以下實用資訊:

  • 標準前景服務:應用程式顯示時啟動的服務,或已獲准啟動背景活動的服務,都會獲得 WIU 存取權。
  • 背景啟動的 FGS (BFSL):大多數使用者不會授予 WIU 存取權。主要例外狀況是授予 WIU 的互動,包括涉及明確使用者意圖的互動,例如通知點擊、小工具互動或來自外部裝置的媒體按鍵事件。
  • 系統已啟動 FGS:FGS 開始使用系統伺服器委派 (例如使用 Telecom Jetpack 程式庫),並獲得 WIU 存取權。

詳情請參閱「從背景啟動前景服務的限制」。

受影響的 Audio 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()