在 Android 10 中,car_audio_configuration.xml
取代 car_volumes_groups.xml
和 IAudioControl.getBusForContext
。在新設定檔中,定義了區域清單。每個區域都會有一或多個含有相關聯裝置的音量群組,而每個裝置都會有應在該區域內路由的內容。所有情境都必須在各個區域中顯示。
設定音訊路由
音訊政策檔案通常位於供應商分區,代表主機板的音訊硬體設定。car_audio_configuration.xml
中參照的所有裝置都必須在 audio_policy_configuration.xml
中定義。
啟用 AAOS 路由
如要使用 AAOS 導向,您必須將 audioUseDynamicRouting
標記設為 true
:
<resources> <bool name="audioUseDynamicRouting">true</bool> </resources>
當 false
時,路由和大部分 CarAudioService
都會停用,作業系統會回復至 AudioService
的預設行為。
主要可用區
根據預設,所有音訊都會轉送至主要區域。只有一個主要區域,在設定中以屬性 isPrimary="true"
表示。
設定範例
舉例來說,車輛可能有兩個區域:主要區域和後座娛樂系統。因此,可能的 car_audio_configuration.xml
定義如下:
<audioZoneConfiguration version="2.0"> <zone name="primary zone" isPrimary="true"> <volumeGroups> <group> <device address="bus0_media_out"> <context context="music"/> <context context="announcement"/> </device> <device address="bus3_call_ring_out"> <context context="call_ring"/> </device> <device address="bus6_notification_out"> <context context="notification"/> </device> <device address="bus7_system_sound_out"> <context context="system_sound"/> <context context="emergency"/> <context context="safety"/> <context context="vehicle_status"/> </device> </group> <group> <device address="bus1_navigation_out"> <context context="navigation"/> </device> <device address="bus2_voice_command_out"> <context context="voice_command"/> </device> </group> <group> <device address="bus4_call_out"> <context context="call"/> </device> </group> <group> <device address="bus5_alarm_out"> <context context="alarm"/> </device> </group> </volumeGroups> </zone> <zone name="rear seat zone" audioZoneId="1"> <volumeGroups> <group> <device address="bus100_rear_seat"> <context context="music"/> <context context="navigation"/> <context context="voice_command"/> <context context="call_ring"/> <context context="call"/> <context context="alarm"/> <context context="notification"/> <context context="system_sound"/> <context context="emergency"/> <context context="safety"/> <context context="vehicle_status"/> <context context="announcement"/> </device> </group> </volumeGroups> </zones> </audioZoneConfiguration>
在此情況下,主要區域已將不同裝置的內容區隔開來。這樣一來,HAL 就能使用車輛的硬體,在每個裝置輸出內容上套用不同的後製效果和混合效果。裝置已分為四個音量群組:媒體、導航、通話和鬧鐘。如果系統已設為 useFixedVolume
,則每個群組的音量會傳遞至 HAL,以便套用至這些裝置的輸出內容。
對於次要區域,預期的輸出內容是透過單一輸出裝置。在這個範例中,所有用途都會路由至單一裝置和音量群組,以簡化操作。
乘客區音訊設定
在 Android 11 中,car_audio_configuration.xml
進一步擴充,推出兩個新欄位:audioZoneId
和 occupantZoneId
。第一個 audioZoneId
可用於進一步控管區域管理。另一方面,occupantZoneId
可用於設定以 User-ID 為依據的路由。
如要使用這些新欄位,您必須使用 car_audio_configuration.xml
的 V2 版本。回到上述的音訊設定,但使用新欄位來對應住戶區 ID 和音訊區 ID,您可以將沒有音量群組定義的新設定設為:
<audioZoneConfiguration version="2.0"> <zone name="primary zone" isPrimary="true" occupantZoneId="0"> ... </zone> <zone name="rear seat zone" audioZoneId="1" occupantZoneId="1"> ... </zone> </zones> </audioZoneConfiguration>
上述設定會將主要區域對應至居住區域 0,並將 audioZoneId
1 對應至 occupantZoneId
1。一般來說,您可以設定任何乘客區和音訊區之間的對應關係,但對應關係必須是一對一。以下是定義這兩個新欄位的規則:
- 主要區域的
audioZoneId
一律為零 audioZoneId
和occupantZoneId
號碼不得重複audioZoneId
和occupantZoneId
只能一對一對應
透過應用程式 UID 進行轉送
在 10 版中,我們在 CarAudioManager
中引進了一系列隱藏的 API,讓應用程式可以查詢及設定音訊區域和焦點。
int[] getAudioZoneIds(); int getZoneIdForUid(int uid); boolean setZoneIdForUid(int zoneId, int uid); boolean clearZoneIdForUid(int uid);
上述 API 可讓第一方應用程式根據應用程式的 UID 管理音訊路由。因此,您也需要音訊區 ID 和應用程式的 UID。有了這些資訊,您就可以使用 CarAudioManager#setZoneIdForUid
API 設定音訊路由。
變更應用程式的區域
根據預設,所有音訊都會傳送至主要區域。如要更新應用程式,將其路由至其他區域,請使用 CarAudioManager#setZoneIdForUid
:
// Find zone to play int zoneId = ... // Find application's uid Int uid = mContext.getPackageManager() .getApplicationInfo(mContext.getPackageName(), 0) .uid; if (mCarAudioManager.setZoneIdForUid(zoneId, info.uid)) { Log.d(TAG, "Zone successfully updated"); } else { Log.d(TAG, "Failed to change zone"); }
N 注意:串流和焦點無法動態切換區域。因此,必須停止播放並重新要求焦點,才能變更區域。
使用 User ID 進行轉送
雖然應用程式的 UID 導向路由可精細控管每個應用程式的音訊路由,但也要求在應用程式實際要求音訊焦點及播放音訊之前,先定義每個應用程式的音訊路由。為緩解這個問題,並進一步協助第三方應用程式在不修改的情況下播放音訊,CarAudioService
會使用車輛乘客區域和音訊區域對應功能,定義以使用者 ID 為基礎的路由。這樣一來,當使用者登入乘客區時,車輛音訊服務就會收到通知。有了這項信號,系統就會自動為所有音訊區域設定音訊焦點管理和路由。
您仍可使用應用程式 UID 型路由,但必須與使用者 ID 路由分開執行。也就是說,如果已定義乘客區到車輛音訊區的對應項目,系統就會停用 UID 導向,且嘗試呼叫 CarAudioManager#setZoneidForUid
時會擲回錯誤。
雖然使用者區域管理功能已簡化音訊路由和焦點管理作業,但使用者仍必須指派至使用者區域。您可以使用 CarOccupantZoneManager#assignProfileUserToOccupantZone
執行這項操作。這個 API 需要管理使用者的權限。目前預期原始設備製造商 (OEM) 會透過某種系統 UI 管理使用者與乘客區的指派作業。完成後,系統會自動為使用者設定應用程式啟動、音訊路由和焦點管理。
使用 setPreferredDevice 進行轉送
除了上述變更之外,Android 11 也提供新的 API,可查詢與每個區域相關聯的輸出裝置,即 CarAudioManager#getOutputDeviceForUsage(int zoneId, int usage)。
這個 API 可用於查詢特定區域的輸出裝置和音訊屬性用途。如此一來,第一方應用程式就能利用播放器的 setPreferredDevice
API,將音訊路由至不同的區域。getOutputDeviceForUsage
API 需要 PERMISSION_CAR_CONTROL_AUDIO_SETTINGS
,且為系統 API。以下是使用 setPreferredDevice
API 找出特定區域的媒體裝置,並將路由導向該裝置的範例。
audioZoneId = ... ; mediaDeviceInfo = mCarAudioManager .getOutputDeviceForUsage(audioZoneId, AudioAttributes.USAGE_MEDIA); … mPlayer.setPreferredDevice(mediaDeviceInfo);