音訊焦點

在開始邏輯串流之前,應用程式會使用與邏輯串流相同的音訊屬性要求音訊焦點。應用程式必須尊重焦點損失,才能在汽車用途中正常運作。

雖然建議您傳送焦點要求,但系統不會強制執行。因此,請將焦點視為間接控制方式,避免在播放期間發生衝突,而非主要的音訊控制機制。車輛不應依賴焦點系統來操作音訊子系統。

焦點互動

為了支援 AAOS,系統會根據要求的 CarAudioContext 與目前焦點持有者之間預先定義的互動,處理音訊焦點要求。互動有三種類型:

  • 獨家
  • 拒絕
  • 並行

獨家互動

這是 Android 最常用的互動模型。

專屬互動中,一次只能有一個應用程式保留焦點。因此,當現有焦點持有者失去焦點時,傳入的焦點要求會獲得焦點。由於兩個應用程式都會播放媒體,因此只允許一個應用程式保留焦點。因此,新啟動的應用程式會傳回焦點要求,並附上 AUDIOFOCUS_REQUEST_GRANTED,而目前播放音樂的應用程式會收到焦點變更事件,並附上與所提出要求類型相對應的遺失狀態。

拒絕互動

在「拒絕」互動中,系統一律會拒絕傳入的要求。例如,在通話期間嘗試播放音樂。在這種情況下,如果撥號應用程式保留通話的音訊焦點,而第二個應用程式要求播放音樂,音樂應用程式會收到 AUDIOFOCUS_REQUEST_FAILED 做為要求的回應。由於焦點要求遭到拒絕,因此不會將焦點遺失事件傳送至目前的焦點持有者。

並行互動

AAOS 專屬的互動類型是並行互動。這樣一來,要求車輛音訊焦點的應用程式就能與其他應用程式同時保留焦點。如要進行並行互動,必須符合下列條件:以下是:

如果符合這些條件,焦點要求會傳回 AUDIOFOCUS_REQUEST_GRANTED,而目前的焦點持有者則不會變更焦點。不過,如果目前的焦點持有者選擇接收 duck 事件,或在 duck 時暫停,則目前的焦點持有者會失去焦點,就像在專屬互動發生時一樣。

處理並行串流

雖然並行互動有許多用途,但請小心在硬體層級混合和抑制輸出裝置。強烈建議您將允許同時播放的 CarAudioContext 例項,路由至不同的輸出裝置。

透過為並行串流提供個別輸出裝置,可讓 HAL 在混合串流前將其中一個串流靜音,或將實體串流路由至車輛中的不同喇叭。如果邏輯串流在 Android 中混合,增益會保持不變,並且會以相同的實體串流的一部分提供。

舉例來說,如果導航和媒體同時傳送,媒體串流的增益值可能會暫時降低 (或降低),以便更清楚地聽到導航指示。或者,您也可以將導航串流傳送至駕駛座喇叭,同時在車內其他地方繼續播放媒體。

互動矩陣

下表顯示 CarAudioService 定義的互動矩陣。每列代表目前焦點持有者的 CarAudioContext,每欄則代表傳入要求的 CarAudioContext

舉例來說,當音樂媒體應用程式在導航應用程式要求焦點時保留焦點,矩陣會指出這兩項互動可同時進行,前提是同時互動的其他條件已滿足。

由於同時進行的互動,可能會有多個焦點持有者。在這種情況下,系統會先比較傳入的焦點要求與目前的焦點持有者,再決定要套用的互動。在這種情況下,最保守的互動會勝出。拒絕、排他,最後是並行。

音訊焦點互動矩陣

圖 1. 音訊焦點互動矩陣。

在 Android 11 中,我們推出了新的使用者設定,讓使用者變更導覽和電話通話之間的互動行為。設定後,android.car.KEY_AUDIO_FOCUS_NAVIGATION_REJECTED_DURING_CALL 會將傳入的 NAVIGATION 焦點要求與目前 CALL 焦點持有者之間的互動,從「同時」變更為「拒絕」。如果使用者希望導航指示不會中斷通話,可以啟用這項設定。這項設定會保留給使用者,且可動態設定,以便後續的焦點要求遵循新設定。

可延遲的音訊焦點

在 Android 11 中,AAOS 新增了支援功能,可要求可延遲的音訊焦點。這樣一來,當非暫時性焦點要求與目前焦點持有者的互動通常會導致拒絕時,系統就會延遲這些要求。一旦焦點變更導致延遲要求可獲得焦點,系統就會核准要求。

延遲音訊焦點要求的規則

  • 僅限非暫時性要求。延遲要求只能針對非暫時性來源提出,以免暫時性音效在相關時間過後仍持續播放。

  • 一次只能延遲一項要求。如果在已有延遲要求的情況下提出可延遲要求,原始延遲要求會收到 AUDIOFOCUS_LOSS 變更事件,而新要求會收到 AUDIOFOCUS_REQUEST_DELAYED 的同步回應。

  • 可延遲的請求必須有 OnAudioFocusChangeListener在要求延遲後,事件監聽器會在要求最終核准 (AUDIOFOCUS_GAIN) 或稍後遭到拒絕 (AUDIOFOCUS_LOSS) 時通知要求者。

要求可延遲的焦點

如要建構可延遲的要求,請按照下列步驟操作:

  1. 使用 AudioFocusRequest.Builder#setAcceptsDelayedFocusGain

    mMediaWithDelayedFocusListener = new MediaWithDelayedFocusListener();
    
    mDelayedFocusRequest = new AudioFocusRequest
         .Builder(AudioManager.AUDIOFOCUS_GAIN)
         .setAudioAttributes(mMusicAudioAttrib)
         .setOnAudioFocusChangeListener(mMediaWithDelayedFocusListener)
         .setForceDucking(false)
         .setWillPauseWhenDucked(false)
         .setAcceptsDelayedFocusGain(true)
         .build();
    
  2. 提出要求時,請處理 AUDIOFOCUS_REQUEST_DELAYED 回應:

    int delayedFocusRequestResults = mAudioManager.requestAudioFocus(mDelayedFocusRequest);
    if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
        // start audio playback
        return;
    }
    if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
         // audio playback delayed to audio focus listener
         return;
    }
    
  3. 當要求延遲時,焦點事件監聽器會處理焦點變更:

    private final class MediaWithDelayedFocusListener implements
    OnAudioFocusChangeListener {
           @Override
           public void onAudioFocusChange(int focusChange) {
               synchronized (mLock) {
                   switch (focusChange) {
                       case AudioManager.AUDIOFOCUS_GAIN:
                            // Start focus playback
                       case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                            // Pause media transiently
                       case AudioManager.AUDIOFOCUS_LOSS:
                            // Stop media
    

系統強制淡出

Android 15 在 AAOS 中推出系統強制執行的音訊淡出功能。在 Android 中,系統不會強制執行音訊焦點。因此,雖然我們鼓勵應用程式開發人員遵守音訊焦點規範,但如果應用程式在失去音訊焦點後仍持續以大音量播放,系統無法阻止這項行為。

在安全至關重要的汽車環境中,遵循音訊焦點十分重要,可盡量減少駕駛人的分心情況。有了這項功能,音訊架構現在會自動淡出失去音訊焦點的應用程式,提供更受控且可預測的音訊體驗。

這項強化功能有助於確保應用程式遵循互動矩陣所定義的音訊焦點遺失決定,避免音訊播放衝突。

整體設計

下圖顯示車輛中焦點遺失功能的高階設計和支援:

系統強制淡出功能的整體設計

圖 2. 系統強制淡出功能的整體設計。

  • 指定淡出:Android 15 中的系統淡出強制執行機制專門針對應用程式失去音訊焦點但仍繼續播放音訊的情況。
  • 淡出機制:當應用程式失去音訊焦點,轉交給新的要求應用程式時:
    • 音訊架構會自動淡出失去音訊的應用程式音訊。
    • 淡出後,系統會將音訊串流設為靜音。
    • 接著,應用程式會收到音訊焦點遺失通知。
    • 系統會將有問題的應用程式設為靜音,直到應用程式重新取得音訊焦點為止。
    • 預設邏輯會淡入 2 秒後淡出。不過,原始設備製造商 (OEM) 可以將這項設定設為任何逾時值。
    • 音訊架構會使用 OEM 設定來執行淡出和淡入作業。
  • 原始設備製造商 (OEM) 設定檔:Android 15 包含新的設定檔 car_audio_fade_configuration.xml

    • 這個檔案可讓原始設備製造商 (OEM) 定義系統的音訊焦點強制執行機制套用至失去焦點的應用程式時的條件。
    • 只有在輸掉的應用程式符合這個 XML 檔案中 OEM 定義的規則時,音訊架構才會強制淡出和靜音。
    • 這項機制可讓原始設備製造商根據應用程式特性或音訊用途類型,自訂功能的行為。
  • 透過 RRO 進行功能控制:我們推出了新的執行階段資源覆蓋 (RRO) 功能旗標 audioUseFadeManagerConfiguration,可用來啟用或停用這項功能:

    • 這項功能預設為停用。
    • 如要啟用系統強制音訊焦點損失功能,原始設備製造商 (OEM) 必須將此標記設為 true
    • 雖然車用音響架構會在啟用標記時預期有效的淡出設定定義,但缺少這類定義不會自動導致致命例外狀況。
    • 所有淡出設定的應用程式都必須有相符的淡出定義。如未提供有效的定義,就以名稱呼叫淡出設定 (做為車輛音訊設定的一部分),會導致嚴重錯誤。
    • 停用標記後,系統會忽略所有淡出設定定義和任何設定參照。

淡出管理員設定

Android 15 音訊架構引進了統一的 FadeManagerConfiguration,可讓原始設備製造商 (OEM) 針對音訊淡出行為進行精細控制。這項架構如圖 3 所示:

淡出管理員設定

圖 3. 淡出管理員設定。

這項設定包括:

  • 淡入/淡出轉場效果屬性:淡出和淡入的設定。
    • 可透過特定音訊用途或屬性定義。
    • 允許自訂時間長度設定。
    • 這些設定可用來建構 VolumeShaper.Configuration
  • 淡出政策:淡出時機的規則。
    • 全域切換鈕,可啟用或停用淡出效果。
    • 可設定的淡出音訊用途清單 (可在失去焦點時淡出)。
    • 排除清單 (無法淡出):防止重要或指定的音訊來源淡出。這些名單可以根據下列項目建立:
      • 內容類型
      • 音訊屬性
      • 應用程式 UID (僅可在執行階段設定)

原始設備製造商 (OEM) 設定

在本節中,我們將介紹可用的原始設備製造商 (OEM) 自訂選項。

汽車音響淡出設定 XML 檔案

Android 15 推出新的設定檔 car_audio_fade_configuration.xml,可讓 OEM 針對焦點遺失時的音訊淡出行為進行全面自訂。

  • 這個 XML 檔案可定義多個不同的淡出設定,每個設定都需要專屬名稱,以便在 car_audio_configuration.xml 中交叉參照。
  • 這些設定可靈活套用於不同的音訊區和區域設定。
  • 值得注意的是,每個淡出設定只接受以毫秒為單位的時間長度值,系統會使用這些值在內部產生對應的 VolumeShaper.Configuration

如需實務實作指南,請參閱 device/generic/car/emulator/audio/car_audio_fade_configuration.xml 中提供的模擬器範例設定。

汽車音響 XML 設定檔

Android 15 推出了更新版 car_audio_configuration.xml 檔案 (目前為第 4 版),其中納入了新的 applyFadeConfigsfadeConfig 標記。applyFadeConfigs 標記可包含多個 fadeConfig 定義,可靈活設定淡出效果。每個定義:

  • 必須包含一個以 isDefault = true 指定的預設 fadeConfig
  • 可包含多個暫時 fadeConfig 定義。這些暫時性設定會在音訊焦點遺失互動期間特別套用,且只有在音訊焦點取得的應用程式符合暫時性設定中定義的條件時才會套用。

如需實務實作指南,請參閱 device/generic/car/emulator/audio/car_audio_configuration.xml 中提供的模擬器範例設定。

OEM 音訊焦點服務擴充功能

導入自訂車輛音訊專注服務的 OEM 廠商,可以靈活地在 OemCarAudioFocusResult 中加入音訊淡出設定。您可以使用 setAudioAttributesToCarAudioFadeConfigurationMap() 建構工具方法完成此操作:

/** @see OemCarAudioFocusResult#getAudioAttributesToCarAudioFadeConfigurationMap() **/
@NonNull
public Builder setAudioAttributesToCarAudioFadeConfigurationMap(@NonNull
        Map<AudioAttributes, CarAudioFadeConfiguration> attrsToCarAudioFadeConfig) {
}

值得注意的是,原始設備製造商可以選擇使用預先設定的啟動時間淡出設定,或是透過自訂音訊焦點服務動態套用設定,提供可調整的控制選項。

流程圖

以下流程圖說明將音訊焦點授予 App2 後的行為,以及 App1 隨後失去音訊焦點的行為:

  • 當車用音訊服務將音訊焦點損失事件傳送至 App1 時,App1 播放器的播放內容會經過由有效 FadeManagerConfiguration 定義的淡出效果。淡出作業完成後,App1 會收到標準的音訊焦點遺失回呼。
  • 您可以選擇在設定的時間長度過後,讓 App1 的音訊淡入。原始設備製造商 (OEM) 可根據特定產品需求,透過 Builder#setFadeInDurationForUsage(int, long) 彈性設定這段時間。

車輛音訊淡出功能的流程圖

圖 4. 車輛音訊淡出功能的序列圖。

多區焦點管理

對於有多個音訊區的車輛,系統會為每個區域分別管理音訊焦點。因此,對一個區域提出的要求不會考量其他區域的焦點持有者,也不會導致其他區域的焦點持有者失去焦點。這樣一來,您就能透過後座娛樂系統單獨管理主車廂的焦點,因此不會因為焦點變更而中斷某個區域的音訊播放。

對於所有應用程式,CarAudioService 會自動管理焦點。焦點要求的音訊區域取決於相關聯的 UserIdUID (詳情請參閱「多區域音訊轉送」)。

同時要求多個區域的音訊

如果應用程式想在多個區域中同時播放音訊,就必須在套件中加入 AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID,為每個區域要求焦點:

//Create attribute with bundle and AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID
Bundle bundle = new Bundle();
bundle.putInt(CarAudioManager.AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID,
               zoneId);

AudioAttributes attributesWithZone = new AudioAttributes.Builder()
     .setUsage(AudioAttributes.USAGE_MEDIA)
     .addBundle(bundle)
     .build();

//Create focus request using built attributesWithZone

這個套件參數可讓要求者覆寫自動音訊區域對應項目,改為使用指定的區域 ID。因此,應用程式可以針對不同的音訊區域發出個別要求。

HAL 音訊焦點

從 Android 11 開始,HAL 可代表外部串流要求焦點。雖然這些 API 屬於選用項目,但我們強烈建議您使用這些 API,讓外部音效成為 Android 生態系統中的最佳參與者,並提供流暢的使用者體驗。

HAL 會就應優先處理哪些聲音做出最終決定。因此,無論 HAL 是否已獲得音訊焦點,都應播放緊急和安全性重要音效,且即使 HAL 失去音訊焦點,也應繼續適當播放。同樣地,任何政府法規規定的聲音也適用這項規定。

播放緊急或安全攸關的聲音時,HAL 應主動將 Android 串流靜音,確保聲音清晰可聞。

AudioControl@2.0

AudioControl HAL 2.0 版推出以下新 API:

API 目的
IAudioControl#registerFocusListener IFocusListener 例項註冊至 AudioControl HAL。這個事件監聽器可讓 HAL 要求及放棄音訊焦點。HAl 會提供 ICloseHandle 例項,供 Android 使用來取消註冊事件監聽器。
IAudioControl#onAudioFocusChange 通知 HAL,針對透過 IFocusListener 提出的焦點要求,變更狀態,包括對初始焦點要求的回應。
IFocusListener#requestAudioFocus 代表 HAL 要求指定用途、區域 ID 和對焦增益類型的對焦功能。
IFocusListener#abandonAudioFocus 放棄現有的 HAL 焦點要求,適用於指定的使用情形和區域 ID。

HAL 可同時提出多個聚焦要求,但每個用途和區域 ID 配對只能有一個要求。Android 會假設 HAL 在收到要求後,會立即開始播放聲音,並持續播放,直到放棄焦點為止。

除了 registerFocusListener 之外,這些要求都是 oneway,可確保 Android 在處理焦點要求時不會延遲 HAL。HAL 應在播放安全攸關的音效前等待取得焦點。HAL 可透過 IAudioControl#onAudioFocusChange 監聽並回應音訊焦點的變更,但這並非必要。

原始設備製造商 (OEM) 車輛音訊焦點服務

在 Android 14 中,AAOS 推出了汽車原始設備製造商外掛程式服務,可讓部分汽車元件具備可設定性。對於車用音訊外掛程式服務,外掛程式服務可讓原始設備製造商管理車用音訊服務攔截的焦點要求。這可讓原始設備製造商在管理焦點時,更靈活地遵循規則和法規。因此,不同製造商和地區的音訊專注互動方式可能有所不同。音訊焦點的基本前提仍適用,應用程式仍應要求焦點,以便妥善管理音訊,提升使用者體驗。一般來說,應用程式提出的音訊專注要求仍須遵守特定規則:

  • 在沒有任何持續性高優先順序音訊焦點 (包括電話、緊急警報或安全通知) 的情況下,應用程式應能暫時或永久獲得音訊焦點。

  • 媒體焦點處於啟用狀態時:

    • 要求呼叫使用焦點的應用程式應能同時或獨占地接聽來電。

    • 要求導覽使用者專注力的應用程式應能同時或獨占地收到導覽專注力。

    • 要求使用助理使用者焦點的應用程式,應能同時或獨占地收到使用者焦點。

  • 當常態高優先順序音訊焦點 (包括電話、緊急警報或安全通知) 應用程式處於啟用狀態時,應根據需要授予或延遲任何傳入的延遲音訊焦點要求。

雖然這些建議並非詳盡無遺,但如果沒有任何有效的高優先順序音效,這些建議可協助要求專注模式的應用程式取得專注模式。即使高優先順序的音效正在播放,系統仍應遵守延遲焦點要求,並在高優先順序音效停止時獲得焦點。