Trong Android 10, car_audio_configuration.xml
sẽ thay thế car_volumes_groups.xml
và IAudioControl.getBusForContext
.
Trong tệp cấu hình mới, danh sách các vùng được xác định. Mỗi vùng có một hoặc nhiều nhóm phương tiện với các thiết bị liên kết và mỗi thiết bị có các ngữ cảnh sẽ được định tuyến trong vùng đó. Tất cả ngữ cảnh đều phải được biểu thị trong mỗi vùng.
Định cấu hình định tuyến âm thanh
Các tệp chính sách âm thanh (thường nằm trong phân vùng của nhà cung cấp) đại diện cho cấu hình phần cứng âm thanh của bo mạch. Tất cả thiết bị được tham chiếu trong car_audio_configuration.xml
phải được xác định trong audio_policy_configuration.xml
.
Bật tính năng định tuyến AAOS
Để sử dụng tính năng định tuyến dựa trên AAOS, bạn phải đặt cờ audioUseDynamicRouting
thành true
:
<resources> <bool name="audioUseDynamicRouting">true</bool> </resources>
Khi false
, tính năng định tuyến và phần lớn CarAudioService
sẽ bị tắt và hệ điều hành sẽ quay lại hành vi mặc định của AudioService
.
Vùng chính
Theo mặc định, tất cả âm thanh sẽ được định tuyến đến vùng chính. Chỉ có thể có một vùng chính, được chỉ định trong cấu hình bằng thuộc tính isPrimary="true"
.
Cấu hình mẫu
Ví dụ: một xe có thể có hai vùng — vùng chính và hệ thống giải trí ở hàng ghế sau. Do đó, car_audio_configuration.xml
có thể được xác định như sau:
<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>
Ở đây, vùng chính đã tách riêng các ngữ cảnh cho các thiết bị khác nhau. Điều này cho phép HAL áp dụng các hiệu ứng xử lý hậu kỳ và kết hợp khác nhau trên mỗi đầu ra thiết bị bằng phần cứng của xe. Các thiết bị được sắp xếp thành 4 nhóm âm lượng: nội dung nghe nhìn, chỉ đường, cuộc gọi và chuông báo. Nếu hệ thống được định cấu hình thành useFixedVolume
, thì các mức âm lượng cho mỗi nhóm sẽ được chuyển vào HAL để áp dụng cho đầu ra của các thiết bị này.
Đối với vùng phụ, kết quả dự kiến là thông qua một thiết bị đầu ra. Trong ví dụ này, tất cả các hoạt động sử dụng đều được định tuyến đến một thiết bị và nhóm phương tiện để đơn giản hoá mọi thứ.
Cấu hình âm thanh cho vùng người ngồi
Trong Android 11, car_audio_configuration.xml
được mở rộng thêm để giới thiệu hai trường mới là audioZoneId
và occupantZoneId
.
Thứ nhất, bạn có thể sử dụng audioZoneId
để kiểm soát việc quản lý vùng tốt hơn.
Mặt khác, bạn có thể sử dụng occupantZoneId
để định cấu hình tính năng định tuyến dựa trên mã nhận dạng người dùng.
Để sử dụng các trường mới này, bạn bắt buộc phải sử dụng phiên bản 2 của car_audio_configuration.xml
. Xem lại cấu hình âm thanh ở trên nhưng sử dụng trường mới để liên kết mã nhận dạng khu vực người ngồi và mã nhận dạng khu vực âm thanh, cấu hình mới không có định nghĩa nhóm âm lượng có thể được thiết lập như sau:
<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>
Cấu hình ở trên xác định mối liên kết cho vùng chính với vùng người ngồi 0 và audioZoneId
1 với occupantZoneId
1. Nhìn chung, bạn có thể định cấu hình mọi mối liên kết giữa vùng người ngồi và vùng âm thanh, nhưng mối liên kết phải là một với một.
Dưới đây là các quy tắc xác định hai trường mới:
audioZoneId
cho múi giờ chính luôn bằng 0- Không được lặp lại số
audioZoneId
vàoccupantZoneId
audioZoneId
vàoccupantZoneId
chỉ có thể có mối liên kết một với một
Định tuyến thông qua UID của ứng dụng
Một loạt API ẩn đã được giới thiệu cho CarAudioManager
trong phiên bản 10 để cho phép các ứng dụng truy vấn và đặt vùng âm thanh cũng như tiêu điểm.
int[] getAudioZoneIds(); int getZoneIdForUid(int uid); boolean setZoneIdForUid(int zoneId, int uid); boolean clearZoneIdForUid(int uid);
Các API ở trên cho phép ứng dụng của bên thứ nhất quản lý việc định tuyến âm thanh dựa trên UID của ứng dụng. Do đó, bạn cũng cần có cả mã nhận dạng vùng âm thanh và UID của ứng dụng. Khi có thông tin đó, bạn có thể thiết lập định tuyến âm thanh bằng cách sử dụng API CarAudioManager#setZoneIdForUid
.
Thay đổi khu vực cho một ứng dụng
Theo mặc định, tất cả âm thanh sẽ được chuyển đến vùng chính. Để cập nhật một ứng dụng được định tuyến đến một vùng khác, hãy sử dụng 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 Lưu ý: Luồng và tiêu điểm không thể tự động chuyển đổi vùng. Do đó, bạn phải dừng phát và yêu cầu lại quyền lấy tiêu điểm để thay đổi vùng.
Định tuyến bằng Mã nhận dạng người dùng
Mặc dù tính năng định tuyến dựa trên UID của ứng dụng cho phép kiểm soát chi tiết việc định tuyến âm thanh của từng ứng dụng, nhưng tính năng này cũng yêu cầu định tuyến âm thanh cho từng ứng dụng trước khi ứng dụng thực sự yêu cầu quyền phát âm thanh và phát âm thanh. Để giảm thiểu vấn đề này và hỗ trợ thêm cho các ứng dụng bên thứ ba phát âm thanh mà không cần sửa đổi, CarAudioService
sử dụng bản đồ vùng người ngồi trong ô tô và vùng âm thanh để xác định tuyến đường dựa trên mã nhận dạng người dùng. Bằng cách này, khi người dùng đăng nhập vào khu vực người ngồi, dịch vụ âm thanh trên ô tô sẽ được thông báo. Với tín hiệu này, tính năng quản lý và định tuyến tiêu điểm âm thanh sẽ tự động được định cấu hình cho tất cả các vùng âm thanh.
Bạn vẫn có thể sử dụng tính năng định tuyến dựa trên UID của ứng dụng nhưng phải thực hiện độc lập với tính năng định tuyến dựa trên mã nhận dạng người dùng. Điều này có nghĩa là nếu bạn xác định mối liên kết giữa vùng người ngồi và vùng âm thanh trên ô tô, thì tính năng định tuyến dựa trên UID sẽ bị tắt và việc cố gắng gọi CarAudioManager#setZoneidForUid
sẽ gặp lỗi.
Mặc dù việc định tuyến âm thanh và quản lý tiêu điểm đã được đơn giản hoá bằng tính năng quản lý khu vực có người, nhưng người dùng vẫn phải được chỉ định cho một khu vực có người. Bạn có thể thực hiện việc này bằng cách sử dụng CarOccupantZoneManager#assignProfileUserToOccupantZone
. API này yêu cầu quyền quản lý người dùng. Hiện tại, các nhà sản xuất thiết bị gốc (OEM) sẽ quản lý việc chỉ định người dùng cho khu vực người ngồi thông qua một số loại giao diện người dùng hệ thống. Sau khi hoàn tất, việc khởi chạy ứng dụng, định tuyến âm thanh, quản lý tiêu điểm sẽ tự động được định cấu hình cho người dùng.
Định tuyến bằng setPreferredDevice
Cùng với những thay đổi ở trên, Android 11 cũng có một API mới để truy vấn các thiết bị đầu ra liên kết với từng vùng, CarAudioManager#getOutputDeviceForUsage(int zoneId, int usage).
Bạn có thể dùng API này để truy vấn thiết bị đầu ra cho một vùng cụ thể và mức sử dụng thuộc tính âm thanh. Theo cách này, các ứng dụng của bên thứ nhất có thể định tuyến âm thanh đến các vùng khác nhau bằng cách sử dụng API setPreferredDevice
của trình phát. API getOutputDeviceForUsage
yêu cầu PERMISSION_CAR_CONTROL_AUDIO_SETTINGS
và là một API hệ thống. Dưới đây là ví dụ về cách tìm thiết bị đa phương tiện cho một vùng cụ thể và định tuyến đến thiết bị đó bằng API setPreferredDevice
.
audioZoneId = ... ; mediaDeviceInfo = mCarAudioManager .getOutputDeviceForUsage(audioZoneId, AudioAttributes.USAGE_MEDIA); … mPlayer.setPreferredDevice(mediaDeviceInfo);