音訊焦點

應用程式必須先使用與邏輯串流相同的音訊屬性要求音訊焦點,才能啟動邏輯串流。應用程式必須尊重焦點遺失,才能在車輛使用情況中正常運作。

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

焦點互動

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

  • 獨家
  • 拒絕
  • 並行

專屬互動

這是最常與 Android 搭配使用的互動模型。

專屬互動中,一次只能有一個應用程式保持焦點。 因此,系統會將焦點授予傳入的焦點要求,而現有的焦點持有者則會失去焦點。由於兩個應用程式都會播放媒體,因此只能有一個應用程式保留焦點。因此,新啟動的應用程式會收到 AUDIOFOCUS_REQUEST_GRANTED 的焦點要求,而目前播放音樂的應用程式則會收到焦點變更事件,其中包含與要求類型相應的焦點遺失狀態。

拒絕互動

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

並行互動

AAOS 的獨特之處在於並行互動。這樣一來,在車輛中要求音訊焦點的應用程式就能與其他應用程式同時保留焦點。如要進行並行互動,必須符合下列條件。「

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

處理並行串流

雖然並行互動有許多用途,但請注意輸出裝置的硬體層級混音和閃避。強烈建議您將允許同時播放的 CarAudioContext 執行個體,路由至不同的輸出裝置。

為並行串流提供獨立的輸出裝置,可讓 HAL 在混合串流前先將其中一個串流調低音量,或將實體串流傳送至車輛中的不同喇叭。如果邏輯串流在 Android 中混合,增益不會改變,並會以相同實體串流的形式傳送。

舉例來說,如果系統同時提供導航和媒體內容,媒體串流的增益可能會暫時降低 (或閃避),讓導航指示更清楚。或者,導覽串流可以傳送到駕駛座側的喇叭,媒體則繼續在車廂其他位置播放。

互動矩陣

下表顯示 CarAudioService 定義的互動矩陣。 每一列代表目前焦點擁有者的 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) 設定檔:Android 15 包含新的設定檔 car_audio_fade_configuration.xml

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

    • 這項功能預設為停用。
    • 如要啟用系統強制執行的音訊焦點遺失,原始設備製造商必須將這個標記設為 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 並非必要,但我們強烈建議使用,讓外部音訊在 Android 生態系統中發揮最佳效果,並提供流暢的使用者體驗。

HAL 會最終決定哪些聲音應優先處理。 因此,無論 HAL 是否獲得音訊焦點,都應播放緊急和安全關鍵音效,即使 HAL 失去音訊焦點,也應繼續適當播放。政府法規規定的任何音效也是如此。

播放緊急或安全相關的重大音效時,HAL 應主動適當調低 Android 串流音量,確保使用者能清楚聽到這些音效。

AudioControl@2.0

AudioControl HAL 2.0 版導入了下列新 API:

API 目的
IAudioControl#registerFocusListener 向 AudioControl HAL 註冊 IFocusListener 例項。這個接聽程式可讓 HAL 要求及捨棄音訊焦點。HAL 提供 ICloseHandle 執行個體,供 Android 用來取消註冊監聽器。
IAudioControl#onAudioFocusChange 將 HAL 提出的對焦要求狀態變更通知 HAL (透過 IFocusListener),包括對初始對焦要求的相關回應。
IFocusListener#requestAudioFocus 要求會代表 HAL 針對指定用途、區域 ID 和焦點增益類型進行。
IFocusListener#abandonAudioFocus 放棄指定用途和區域 ID 的現有 HAL 焦點要求。

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

除了 registerFocusListener 之外,這些要求都是 oneway,可確保 Android 在處理焦點要求時不會延遲 HAL。HAL 不應等待取得焦點,再播放安全關鍵音效。HAL 可以選擇是否要透過 IAudioControl#onAudioFocusChange 監聽及回應音訊焦點的變化。

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

在 Android 14 中,AAOS 導入了車輛 OEM 外掛程式服務,可設定部分車輛元件。對於車輛音訊外掛程式服務,外掛程式服務可讓原始設備製造商管理車輛音訊服務攔截的焦點要求。這可讓原始設備製造商更彈性地管理焦點,以符合規則和法規要求。因此,音訊焦點互動方式可能因製造商和地區而異。音訊焦點的基本前提仍然成立,也就是應用程式應要求焦點,以便更妥善地管理音訊,進而提升使用者體驗。一般來說,應用程式的音訊焦點要求仍須遵守特定規則:

  • 如果沒有任何持續性高優先順序音訊焦點 (包括電話、緊急快訊或安全通知),應用程式應能暫時或永久取得音訊焦點。

  • 媒體焦點啟用時:

    • 要求通話使用權的應用程式應能同時或專屬接收通話。

    • 要求導航使用專注模式的應用程式應能同時或專屬接收導航專注模式。

    • 要求使用助理的應用程式應能同時或專屬接收使用焦點。

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

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