Triển khai đài phát thanh

Trang này giải thích cách triển khai radio ở cấp độ phần cứng và phần mềm.

Thành phần hệ thống

Ngăn xếp đài phát sóng bao gồm các thành phần sau.

Kiến trúc đài phát sóng
Hình 1. Kiến trúc đài phát thanh

Ứng dụng tham khảo radio

Để biết chi tiết về cách triển khai điều khiển vô tuyến, hãy xem Triển khai điều khiển vô tuyến .

Một ứng dụng radio Java mẫu ( packages/apps/Car/Radio ) đóng vai trò triển khai tham chiếu. Khi dịch vụ ứng dụng khởi động, nó sẽ yêu cầu Trình quản lý Radio mở Radio Tuner. Sau đó, ứng dụng có thể gửi yêu cầu tới Bộ dò đài, chẳng hạn như dò đài, tần số cụ thể hoặc tìm kiếm đài phát thanh có sẵn tiếp theo. Ứng dụng nhận các bản cập nhật từ Trình quản lý Radio và Bộ dò đài trong Radio, chẳng hạn như thông tin chương trình hiện tại, danh sách chương trình radio, cấu hình và thông số do nhà cung cấp xác định. Ứng dụng Radio tham chiếu chỉ hỗ trợ đài AM và FM. OEM có thể sửa đổi hoặc thay thế ứng dụng Radio theo ý muốn.

Quản lý đài phát thanh

Khi ứng dụng yêu cầu Trình quản lý vô tuyến mở bộ dò sóng, Trình quản lý vô tuyến ( frameworks/base/core/java/android/hardware/radio/RadioManager.java ) yêu cầu Dịch vụ phát sóng vô tuyến mở phiên Bộ điều chỉnh và sau đó kết thúc phiên trong một Radio Tuner ( frameworks/base/core/java/android/hardware/radio/RadioTuner.java ), được trả về ứng dụng. Radio Tuner xác định các API (chẳng hạn như điều chỉnh, bước và hủy) có thể được gọi từ các ứng dụng radio và gửi yêu cầu đến Dịch vụ Radio Broadcast. Các phương thức gọi lại ( RadioTuner.Callback ) được xác định trong Radio Tuner gửi thông tin cập nhật về đài phát sóng HAL, chẳng hạn như thông tin chương trình hiện tại, danh sách chương trình và các tham số do nhà cung cấp xác định, từ Dịch vụ phát sóng vô tuyến đến các ứng dụng.

Dịch vụ phát thanh truyền hình

Dịch vụ Broadcast Radio ( frameworks/base/services/core/java/com/android/server/broadcastradio ) là dịch vụ khách cho Broadcast Radio HAL. Dịch vụ Radio Phát sóng điều phối nhiều Nhà quản lý Radio với HAL của Radio Broadcast. Dịch vụ vô tuyến phát sóng hỗ trợ ngôn ngữ định nghĩa giao diện HAL (HIDL)ngôn ngữ định nghĩa giao diện Android (AIDL) phát sóng HAL. Dịch vụ Radio Phát sóng liên kết với AIDL HAL khi có bất kỳ dịch vụ AIDL HAL nào tồn tại; mặt khác, dịch vụ sẽ liên kết đến HIDL HAL. Dịch vụ vô tuyến phát sóng tạo Mô-đun vô tuyến cho từng phiên bản HAL có sẵn (chẳng hạn như AM, FM và DAB).

Mỗi Trình quản lý vô tuyến có thể yêu cầu Dịch vụ vô tuyến phát sóng tạo phiên điều chỉnh trên Mô-đun vô tuyến tương ứng, dựa trên loại radio. Mỗi phiên điều chỉnh có thể gọi các phương thức, chẳng hạn như điều chỉnh, bước và hủy (được xác định trong giao diện HAL) để thực hiện các thao tác trên phiên bản HAL radio phát sóng tương ứng. Khi một phiên bộ điều chỉnh nhận được lệnh gọi lại từ phiên bản HAL trên bản cập nhật HAL, chẳng hạn như thông tin chương trình hiện tại, danh sách chương trình, cờ cấu hình và thông số nhà cung cấp, lệnh gọi lại về bản cập nhật sẽ được gửi đến tất cả Bộ dò sóng vô tuyến được liên kết với cùng một Mô-đun vô tuyến.

Đài phát thanh HAL

Để tìm hiểu thêm về giao diện HIDL và AIDL của đài phát thanh cũng như sự khác biệt giữa hai giao diện này, hãy xem Giao diện HAL của đài phát thanh .

Lớp trừu tượng phần cứng vô tuyến phát sóng

Các phần sau đây mô tả cách làm việc với lớp trừu tượng phần cứng (HAL) để triển khai đài phát thanh.

Giao diện HAL của đài phát thanh

Đài phát sóng HAL cung cấp các cấu trúc dữ liệu và giao diện ở cấp độ phần cứng để triển khai đài phát sóng, chẳng hạn như đài AM/FM và DAB.

Giao diện HIDL 2.0 và AIDL

Đài phát thanh HAL sử dụng các giao diện được mô tả trong các phần sau.

Người nghe thông báo

IAnnouncementListener là giao diện gọi lại cho người nghe thông báo, có thể được đăng ký trên đài phát sóng HAL để nhận thông báo. Giao diện có các phương thức sau:

IAnnouncementListener
Mô tả: Được gọi bất cứ khi nào danh sách thông báo có thay đổi.
HIDL 2.0 oneway onListUpdated(vec<Announcement> announcements)
AIDL oneway void onListUpdated(in Announcement[] announcements)
Đóng tay cầm

ICloseHandle là hàm đóng chung để loại bỏ lệnh gọi lại không cần giao diện hoạt động.

IĐóngXử lý
Mô tả: Đóng tay cầm.
HIDL 2.0 close()
AIDL void close()

Giao diện gọi lại

ITunerCallback là giao diện gọi lại được gọi bởi đài phát thanh HAL để gửi thông tin cập nhật cho dịch vụ khách hàng HAL.

iTunesGọi lại
Mô tả: Được HAL gọi khi một thao tác điều chỉnh (điều chỉnh, tìm kiếm (trong AIDL) hoặc quét (trong HIDL) và bước thành công) không thành công một cách không đồng bộ.
HIDL 2.0 oneway onCurrentProgramInfoChanged(ProgramInfo info)
AIDL void onCurrentProgramInfoChanged(in ProgramInfo info)
Mô tả: Được gọi khi dò, tìm kiếm (trong AIDL) hoặc quét (trong HIDL) hoặc bước thành công.
HIDL 2.0 oneway onTuneFailed(Result result, ProgramSelector selector)
AIDL void onTuneFailed(in Result result, in ProgramSelector selector)
Mô tả: Được gọi khi dò, tìm kiếm (trong AIDL) hoặc quét (trong HIDL) hoặc bước thành công.
HIDL 2.0 oneway onCurrentProgramInfoChanged(ProgramInfo info)
AIDL void onCurrentProgramInfoChanged(in ProgramInfo info)
Mô tả: Được gọi khi danh sách chương trình được cập nhật; kích thước của mỗi đoạn nên được giới hạn ở 500kiB.
HIDL 2.0 oneway onProgramListUpdated(ProgramListChunk chunk)
AIDL oneway onProgramListUpdated(ProgramListChunk chunk)
Mô tả: Được gọi khi ăng-ten được kết nối hoặc ngắt kết nối.
HIDL 2.0 oneway onAntennaStateChange(bool connected)
AIDL void onCurrentProgramInfoChanged(in ProgramInfo info)
Mô tả: Được gọi khi các giá trị tham số dành riêng cho nhà cung cấp được cập nhật nội bộ trong HAL (không nên gọi sau khi gọi setParameters bởi máy khách HAL).
HIDL 2.0 oneway onParametersUpdated(vec<VendorKeyValue> parameters)
AIDL void onParametersUpdated(in VendorKeyValue[] parameters)
Mô tả: Mới trong AIDL. Được gọi khi cờ cấu hình được cập nhật nội bộ trong HAL (không nên gọi sau khi gọi setConfigFlag bằng máy khách HAL).
HIDL 2.0 Không áp dụng được.
AIDL void onConfigFlagUpdated(in ConfigFlag flag, in boolean value)

Giao diện HAL của đài phát sóng chính

IBroadcastRadio là giao diện chính cho đài phát thanh HAL. Trong HIDL 2.0 HAL, sử dụng giao diện ITunerSession cho bộ điều chỉnh để gọi các hoạt động. Tuy nhiên, nhiều nhất chỉ có một bộ điều chỉnh hoạt động tại một thời điểm (với điều kiện là mỗi phiên bản HAL của đài phát sóng chỉ có một chip điều chỉnh). ITunerSession đã bị xóa khỏi giao diện AIDL và giao diện của nó được chuyển sang IBroadcastRadio .

IBroadcastRadio
Mô tả: Nhận mô tả về mô-đun và khả năng của nó.
HIDL 2.0 getProperties() generates (Properties properties)
AIDL Properties getProperties()
Mô tả: Tìm nạp cấu hình vùng AM/FM hiện tại hoặc có thể.
HIDL 2.0 getAmFmRegionConfig(bool full) generates (Result result, AmFmRegionConfig config)
AIDL AmFmRegionConfig getAmFmRegionConfig(bool full)
Mô tả: Tìm nạp cấu hình vùng DAB hiện tại.
HIDL 2.0 getDabRegionConfig() generates (Result result, vec<DabTableEntry> config)
AIDL DabTableEntry[] getDabRegionConfig()
Mô tả: Lấy hình ảnh từ bộ nhớ đệm của mô-đun radio. Trong AIDL, kích thước hình ảnh phải nhỏ hơn 1MB do giới hạn cứng đối với bộ đệm giao dịch liên kết.
HIDL 2.0 getImage(uint32_t id) generates (vec<uint8_t> image)
AIDL byte[] getImage(in int id)
Mô tả: Đăng ký người nghe thông báo.
HIDL 2.0 registerAnnouncementListener(vec<AnnouncementType> enabled,IAnnouncementListener listener) generates (Result result, ICloseHandle closeHandle)
AIDL ICloseHandle registerAnnouncementListener(in IAnnouncementListener listener, in AnnouncementType[] enabled)
Sự miêu tả:
  • HIDL HAL: Khi mở phiên điều chỉnh mới, phiên cũ phải được chấm dứt.
  • AIDL HAL: Vì không có phiên điều chỉnh nào nên chỉ cần đặt lệnh gọi lại bộ điều chỉnh. Nếu nó tồn tại, cuộc gọi lại cũ sẽ không được đặt.
HIDL 2.0 openSession(ITunerCallback callback) tạo ra (Result result, ITunerSession session)
AIDL void setTunerCallback(in ITunerCallback callback)
Sự miêu tả:
  • HIDL HAL: Việc đóng phiên điều chỉnh không được thất bại và chỉ được thực hiện một lần.
  • AIDL HAL: Không có bộ điều chỉnh và chỉ cần hủy đặt lệnh gọi lại bộ điều chỉnh.
HIDL 2.0 close()
AIDL unsetTunerCallback()
Mô tả: Điều chỉnh theo một chương trình cụ thể.
HIDL 2.0 tune(ProgramSelector program) generates (Result result)
AIDL void tune(in ProgramSelector program)
Mô tả: Tìm kiếm chương trình hợp lệ tiếp theo được phát sóng . Để tránh nhầm lẫn trong AIDL, scan được đổi tên thành seek .
HIDL 2.0 scan(bool directionUp, bool skipSubChannel) generates (Result result)
AIDL void seek(in boolean directionUp, in boolean skipSubChannel)
Mô tả: Các bước tới kênh lân cận, kênh này có thể không bị chiếm bởi bất kỳ chương trình nào.
HIDL 2.0 step(bool directionUp) generates (Result result)
AIDL void step(in boolean directionUp)
Mô tả: Hủy các thao tác điều chỉnh, quét (trong HIDL) hoặc tìm kiếm (trong AIDL) hoặc từng bước đang chờ xử lý.
HIDL 2.0 cancel()
AIDL void cancel()
Mô tả: Áp dụng bộ lọc cho danh sách chương trình và bắt đầu gửi thông tin cập nhật danh sách chương trình qua lệnh gọi lại onProgramListUpdated .
HIDL 2.0 startProgramListUpdates(ProgramFilter filter) generates (Result result)
AIDL void startProgramListUpdates(in ProgramFilter filter)
Mô tả: Dừng gửi cập nhật danh sách chương trình.
HIDL 2.0 stopProgramListUpdates()
AIDL void stopProgramListUpdates()
Mô tả: Tìm nạp cài đặt hiện tại của cờ cấu hình nhất định.
HIDL 2.0 isConfigFlagSet(ConfigFlag flag) generates (Result result, bool value)
AIDL boolean isConfigFlagSet(in ConfigFlag flag)
Mô tả: Đặt cờ cấu hình đã cho.
HIDL 2.0 setConfigFlag(ConfigFlag flag, bool value) generates (Result result)
AIDL void setConfigFlag(in ConfigFlag flag, boolean value)
Mô tả: Đặt giá trị tham số dành riêng cho nhà cung cấp.
HIDL 2.0 setParameters(vec<VendorKeyValue> parameters)

tạo ra ,

(vec<VendorKeyValue> results)
AIDL VendorKeyValue[] setParameters(in VendorKeyValue[] parameters)
Mô tả: Truy xuất các giá trị tham số dành riêng cho nhà cung cấp.
HIDL 2.0 getParameters(vec<string> keys) generates (vec<VendorKeyValue> parameters)
AIDL VendorKeyValue[] getParameters(in String[] keys)

Làm rõ giao diện

Hành vi không đồng bộ

Vì mỗi thao tác điều chỉnh (ví dụ: điều chỉnh, quét (trong HIDL) hoặc tìm kiếm (trong AIDL) và bước) có thể tốn thời gian và luồng không bị chặn trong thời gian dài, nên thao tác đó sẽ lên lịch cho các hoạt động tốn thời gian xảy ra sau đó và nhanh chóng trả về một trạng thái hoặc kết quả. Cụ thể, mỗi thao tác nên:

  • Hủy bỏ tất cả các hoạt động điều chỉnh đang chờ xử lý.
  • Kiểm tra xem hoạt động có thể được xử lý hay không dựa trên đầu vào phương thức và trạng thái của bộ dò.
  • Lên lịch tác vụ điều chỉnh và sau đó trả về Result (trong HIDL) hoặc status (trong AIDL) ngay lập tức. Nếu Result hoặc statusOK , lệnh gọi lại bộ điều chỉnh tuneFailed hoặc currentProgramInfoChanged phải được gọi khi tác vụ điều chỉnh không thành công (ví dụ: do hết thời gian chờ) hoặc đã hoàn tất.

Tương tự, startProgramListUpdates cũng lên lịch cho nhiệm vụ tốn nhiều thời gian là cập nhật danh sách chương trình để diễn ra sau và nhanh chóng trả về trạng thái hoặc kết quả. Phương pháp này trước tiên sẽ hủy các yêu cầu cập nhật đang chờ xử lý, sau đó lên lịch cho tác vụ cập nhật và nhanh chóng trả về kết quả.

Điều kiện của cuộc đua

Do hoạt động điều chỉnh không đồng bộ (ví dụ: điều chỉnh, quét (trong HIDL) hoặc tìm kiếm (trong AIDL) và bước), tồn tại tình trạng tương tranh giữa việc hủy thao tác và các hoạt động điều chỉnh. Nếu cancel được gọi sau khi HAL hoàn thành thao tác điều chỉnh và trước khi lệnh gọi lại hoàn tất, lệnh hủy có thể bị bỏ qua và lệnh gọi lại sẽ hoàn tất và được máy khách HAL nhận.

Tương tự, nếu stopProgramListUpdates được gọi sau khi HAL hoàn thành cập nhật danh sách chương trình và trước khi lệnh gọi lại onCurrentProgramInfoChanged hoàn tất, thì stopProgramListUpdates có thể bị bỏ qua và lệnh gọi lại sẽ hoàn tất.

Giới hạn kích thước dữ liệu

Vì có giới hạn cứng đối với bộ đệm giao dịch liên kết nên giới hạn dữ liệu đối với một số phương thức giao diện truyền dữ liệu có kích thước lớn sẽ được làm rõ trong AIDL HAL.

  • getImage yêu cầu hình ảnh được trả về dưới 1 MB.
  • onProgramListUpdate yêu cầu mỗi chunk phải nhỏ hơn 500kiB. Danh sách chương trình lớn hơn phải được chia thành nhiều phần bằng cách triển khai HAL và gửi qua nhiều lệnh gọi lại.

Những thay đổi trong cấu trúc dữ liệu AIDL HAL

Ngoài những thay đổi về giao diện, những thay đổi này còn được áp dụng cho cấu trúc dữ liệu được xác định trong đài phát thanh AIDL HAL, tận dụng lợi thế của AIDL.

  • Constant enum bị xóa trong AIDL và được định nghĩa là const int trong IBroadcastRadio . Trong khi đó, ANTENNA_DISCONNECTED_TIMEOUT_MS được đổi tên thành ANTENNA_STATE_CHANGE_TIMEOUT_MS . Một const int TUNER_TIMEOUT_MS mới được thêm vào. Tất cả các thao tác điều chỉnh, tìm kiếm và bước phải được hoàn thành trong thời gian này.
  • Enum RDSDeemphasis bị xóa trong AIDL và được định nghĩa là const int trong AmFmRegionConfig . Tương ứng, cả fmDeemphasisfmRds trong ProgramInfo đều được khai báo là int, kết quả tính toán bit của các cờ tương ứng. Trong khi đó, D50D75 được đổi tên lần lượt thành DEEMPHASIS_D50DEEMPHASIS_D75 .
  • Enum ProgramInfoFlags bị xóa trong AIDL và được định nghĩa là const int trong ProgramInfo với tiền tố FLAG_ được thêm vào. Tương ứng, infoFlags trong ProgramInfo được khai báo là int, là kết quả tính toán bit của cờ. TUNED cũng được đổi tên thành FLAG_TUNABLE , để mô tả rõ hơn định nghĩa của nó rằng đài có thể được điều chỉnh theo.
  • Trong AmFmBandRange , scanSpacing được đổi tên thành seekSpacing , vì scan được đổi tên thành seek trong AIDL.
  • Do khái niệm hợp nhất được giới thiệu trong AIDL nên MetadataKeyMetadata được xác định trong HIDL HAL không còn được sử dụng nữa. Metadata hợp nhất AIDL được xác định trong AIDL HAL. Mỗi giá trị enum trước đây trong MetadataKey giờ đây là một trường trong Metadata với loại chuỗi hoặc int, tùy thuộc vào định nghĩa của chúng.

Thực hiện điều khiển vô tuyến

Việc triển khai điều khiển vô tuyến dựa trên MediaSessionMediaBrowse , cho phép các ứng dụng Trợ lý giọng nói và Phương tiện điều khiển radio. Để biết thêm thông tin, hãy xem Xây dựng ứng dụng đa phương tiện cho ô tô trên dev.android.com.

Việc triển khai cây duyệt phương tiện được cung cấp trong thư viện car-broadcastradio-support trong packages/apps/Car/libs . Thư viện này cũng chứa các phần mở rộng của ProgramSelector để chuyển đổi sang và từ URI. Khuyến nghị triển khai radio nên sử dụng thư viện này để xây dựng cây duyệt liên quan.

Bộ chuyển đổi nguồn phương tiện

Để cung cấp quá trình chuyển đổi liền mạch giữa radio và các ứng dụng khác được hiển thị trên phương tiện, thư viện car-media-common chứa các lớp cần được tích hợp vào ứng dụng radio. MediaAppSelectorWidget có thể được bao gồm trong XML cho ứng dụng radio (biểu tượng và trình đơn thả xuống được sử dụng trong các ứng dụng radio và phương tiện tham chiếu):

<com.android.car.media.common.MediaAppSelectorWidget
     android:id="@+id/app_switch_container"
     android:layout_width="@dimen/app_switch_widget_width"
     android:layout_height="wrap_content"
     android:background="@drawable/app_item_background"
     android:gravity="center" />

Tiện ích này khởi chạy AppSelectionFragment , hiển thị danh sách các nguồn phương tiện có thể được chuyển sang. Nếu muốn có một giao diện người dùng khác với giao diện người dùng được cung cấp, bạn có thể tạo một tiện ích tùy chỉnh để khởi chạy AppSelectionFragment khi trình chuyển đổi sẽ được hiển thị.

AppSelectionFragment newFragment = AppSelectionFragment.create(widget,
            packageName, fullScreen);
    newFragment.show(mActivity.getSupportFragmentManager(), null);

Việc triển khai mẫu được cung cấp trong quá trình triển khai ứng dụng radio tham chiếu, nằm trong packages/apps/Car/Radio .

Thông số điều khiển chi tiết

Giao diện MediaSession (thông qua MediaSession.Callback ) cung cấp các cơ chế điều khiển cho chương trình radio hiện đang phát:

  • onPlay , onStop . (Bỏ) tắt tiếng phát lại đài.
  • onPause . Tạm dừng thay đổi thời gian (nếu được hỗ trợ).
  • onPlayFromMediaId . Phát bất kỳ nội dung nào từ thư mục cấp cao nhất. Ví dụ: "Play FM" hoặc "Play Radio".
  • onPlayFromUri . Chơi một tần số cụ thể. Ví dụ: "Phát FM 88,5."
  • onSkipToNext , onSkipToPrevious . Dò đến đài tiếp theo hoặc trước đó.
  • onSetRating . Thêm hoặc xóa khỏi Mục ưa thích.

MediaBrowser hiển thị MediaItem có thể điều chỉnh được qua ba loại thư mục cấp cao nhất:

  • ( Tùy chọn ) Chương trình (trạm). Chế độ này thường được sử dụng bởi bộ thu sóng kép để chỉ báo tất cả các đài phát thanh có thể điều chỉnh được tại vị trí của người dùng.
  • Yêu thích. Các chương trình radio được thêm vào danh sách Yêu thích, một số có thể không khả dụng (ngoài phạm vi thu sóng).
  • Các kênh ban nhạc. Tất cả các kênh vật lý có thể có trong khu vực hiện tại (87,9, 88,1, 88,3, 88,5, 88,7, 88,9, 89,1, v.v.). Mỗi ban nhạc có một thư mục cấp cao nhất riêng biệt.
Cấu trúc cây MediaBrowserService
Hình 2. Cấu trúc cây MediaBrowserService

Mỗi thành phần trong mỗi thư mục này (AM/FM/Programs) là một MediaItem có URI có thể được sử dụng với MediaSession để điều chỉnh. Mỗi thư mục cấp cao nhất (AM/FM/Programs) là một MediaItem có mediaId có thể được sử dụng với MediaSession để kích hoạt phát lại và tùy theo quyết định của OEM. Ví dụ: "Play FM", "Play AM" và "Play Radio" đều là các truy vấn radio không cụ thể sử dụng mediaId để gửi tới ứng dụng radio OEM. Tùy thuộc vào ứng dụng radio để xác định nội dung sẽ phát từ yêu cầu chung và mediaId.

Phiên truyền thông

Do không có khái niệm tạm dừng luồng phát sóng nên các hành động Phát, Tạm dừng và Dừng không phải lúc nào cũng áp dụng cho radio. Với radio, hành động Dừng được liên kết với việc tắt tiếng luồng trong khi Phát được liên kết với việc loại bỏ chế độ tắt tiếng.

Một số bộ dò đài (hoặc ứng dụng) cung cấp khả năng mô phỏng việc tạm dừng luồng phát sóng bằng cách lưu nội dung vào bộ nhớ đệm rồi phát lại sau. Trong những trường hợp như vậy, hãy sử dụng onPause .

Việc phát từ các hành động mediaId và URI nhằm mục đích dò kênh được tìm nạp từ giao diện MediaBrowser. mediaId là một chuỗi tùy ý được ứng dụng radio cung cấp để áp đặt một giá trị duy nhất (vì vậy một ID nhất định chỉ trỏ đến một mục) và giá trị ổn định (để một mục nhất định có cùng một ID trong toàn bộ phiên) để xác định một đài nhất định . URI sẽ có một lược đồ được xác định rõ ràng. Nói tóm lại, một dạng ProgramSelector được URI hóa. Mặc dù điều này bảo toàn thuộc tính duy nhất nhưng nó không cần phải ổn định, mặc dù nó có thể thay đổi khi trạm chuyển sang tần số khác.

Theo thiết kế, onPlayFromSearch không được sử dụng. Trách nhiệm của khách hàng (ứng dụng đồng hành) là chọn kết quả tìm kiếm từ cây MediaBrowser. Việc chuyển trách nhiệm đó sang ứng dụng radio sẽ làm tăng độ phức tạp, yêu cầu các hợp đồng chính thức về cách xuất hiện các truy vấn chuỗi và dẫn đến trải nghiệm người dùng không đồng đều trên các nền tảng phần cứng khác nhau.

Lưu ý: Ứng dụng radio không chứa thông tin bổ sung hữu ích để tìm kiếm tên đài không được hiển thị cho khách hàng thông qua giao diện MediaBrowser.

Chuyển sang trạm tiếp theo hoặc trạm trước tùy thuộc vào bối cảnh hiện tại:

  • Khi một ứng dụng được dò đến một đài từ danh sách Mục ưa thích, ứng dụng đó có thể chuyển sang đài tiếp theo từ danh sách Mục ưa thích.
  • Việc nghe một đài từ danh sách Chương trình có thể dẫn đến việc điều chỉnh sang đài có sẵn tiếp theo, được sắp xếp theo số kênh.
  • Việc nghe một kênh tùy ý có thể dẫn đến việc điều chỉnh sang kênh vật lý tiếp theo, ngay cả khi không có tín hiệu phát sóng.

Ứng dụng radio xử lý các hành động này.

Xử lý lỗi

Các hành động TransportControls (Play, Stop và Next) không cung cấp phản hồi về việc liệu hành động đó có thành công hay không. Cách duy nhất để chỉ ra lỗi là đặt trạng thái MediaSession thành STATE_ERROR kèm theo thông báo lỗi.

Ứng dụng radio phải xử lý các hành động đó và thực thi chúng hoặc đặt trạng thái lỗi. Nếu lệnh Phát không được thực hiện ngay lập tức thì trạng thái phát lại phải được thay đổi thành STATE_CONNECTING (trong trường hợp điều chỉnh trực tiếp) hoặc STATE_SKIPPING_TO_PREVIOUS hoặc NEXT trong khi lệnh đang được thực thi.

Khách hàng nên xem PlaybackState và xác minh rằng phiên đã thay đổi chương trình hiện tại thành chương trình được yêu cầu hoặc được đưa vào trạng thái lỗi. STATE_CONNECTING không được vượt quá 30 giây. Tuy nhiên, việc điều chỉnh trực tiếp tới tần số AM/FM nhất định sẽ hoạt động nhanh hơn nhiều.

Thêm và xóa mục yêu thích

MediaSession có hỗ trợ xếp hạng, có thể được sử dụng để kiểm soát Mục yêu thích. onSetRating được gọi với xếp hạng loại RATING_HEART sẽ thêm hoặc xóa đài hiện được dò vào hoặc khỏi danh sách Yêu thích.

Trái ngược với các cài đặt trước cũ, mô hình này giả định danh sách Mục yêu thích không có thứ tự và không bị ràng buộc, khi mỗi mục yêu thích đã lưu được phân bổ vào một ô số (thường từ 1 đến 6). Kết quả là các hệ thống dựa trên cài đặt sẵn sẽ không tương thích với hoạt động onSetRating .

Hạn chế của API MediaSession là chỉ có thể thêm hoặc xóa đài hiện đang được dò. Ví dụ: các mục phải được chọn trước khi có thể xóa chúng. Đây chỉ là một hạn chế của ứng dụng khách MediaBrowser, chẳng hạn như ứng dụng đồng hành. Ứng dụng radio không bị hạn chế tương tự. Phần này là tùy chọn khi ứng dụng không hỗ trợ Mục yêu thích.

Trình duyệt phương tiện

Để biểu thị tần số hoặc tên kênh vật lý nào (khi dò kênh tùy ý phù hợp với công nghệ vô tuyến nhất định) hợp lệ cho một vùng nhất định, tất cả các kênh (tần số) hợp lệ sẽ được liệt kê cho mỗi băng tần. Tại khu vực Hoa Kỳ, con số này lên tới 101 kênh FM trong dải tần từ 87,8 đến 108,0 MHz (sử dụng khoảng cách 0,2 MHz) và 117 kênh AM trong dải tần từ 530 đến 1700 kHz (sử dụng khoảng cách 10kHz). Vì đài HD sử dụng cùng một không gian kênh nên nó không được trình bày riêng biệt.

Danh sách các chương trình radio hiện có sẵn không có gì khác biệt ở chỗ điều này không cho phép các sơ đồ hiển thị như nhóm theo nhóm phát sóng âm thanh trực tiếp (DAB).

Các mục trong danh sách Yêu thích có thể không điều chỉnh được. Ví dụ: nếu một chương trình nhất định nằm ngoài phạm vi. Ứng dụng radio có thể phát hiện hoặc không phát hiện xem mục nhập có thể được điều chỉnh trước hay không. Nếu vậy, nó có thể không đánh dấu mục này là có thể chơi được.

Để xác định các thư mục cấp cao nhất, cơ chế tương tự được Bluetooth sử dụng sẽ được áp dụng. Nghĩa là, gói Extras của đối tượng MediaDescription chứa trường dành riêng cho bộ điều chỉnh giống như Bluetooth thực hiện với EXTRA_BT_FOLDER_TYPE . Trong trường hợp đài phát thanh, điều này dẫn đến việc xác định các trường mới sau trong API công khai:

  • EXTRA_BCRADIO_FOLDER_TYPE = "android.media.extra.EXTRA_BCRADIO_FOLDER_TYPE" . Một trong các giá trị sau:
    • BCRADIO_FOLDER_TYPE_PROGRAMS = 1 . Các chương trình hiện có.
    • BCRADIO_FOLDER_TYPE_FAVORITES = 2 . Yêu thích.
    • BCRADIO_FOLDER_TYPE_BAND = 3 . Tất cả các kênh vật lý cho một băng tần nhất định.

    Không cần xác định bất kỳ trường siêu dữ liệu tùy chỉnh dành riêng cho đài nào vì tất cả dữ liệu liên quan đều phù hợp với sơ đồ MediaBrowser.MediaItem hiện có:

    • Tên chương trình (RDS PS, tên dịch vụ DAB). MediaDescription.getTitle .
    • Tần số FM. URI (xem ProgramSelector ) hoặc MediaDescription.getTitle (nếu một mục nhập nằm trong thư mục BROADCASTRADIO_FOLDER_TYPE_BAND ).
    • Mã định danh dành riêng cho sóng vô tuyến (RDS PI, DAB SId). MediaDescription.getMediaUri được phân tích cú pháp thành ProgramSelector.

    Thông thường, không cần tìm nạp tần số FM cho một mục nhập trên chương trình hiện tại hoặc danh sách Yêu thích (vì máy khách sẽ hoạt động trên ID phương tiện). Tuy nhiên, nếu nhu cầu đó nảy sinh (ví dụ: vì mục đích hiển thị), thì nhu cầu đó sẽ xuất hiện trong URI và có thể được phân tích cú pháp thành ProgramSelector . Điều đó có nghĩa là bạn không nên sử dụng URI để chọn các mục trong phiên hiện tại. Để biết chi tiết, xem ProgramSelector .

    Để tránh các vấn đề liên quan đến hiệu suất hoặc chất kết dính, dịch vụ MediaBrowser phải hỗ trợ phân trang:

    Lưu ý: Theo mặc định, tính năng phân trang được triển khai theo mặc định trong biến thể onLoadChildren() mà không cần xử lý tùy chọn.

    Các mục liên quan từ tất cả các loại danh sách (kênh thô, chương trình được tìm thấy và mục yêu thích) có thể có các ID phương tiện khác nhau (tùy thuộc vào ứng dụng radio; thư viện hỗ trợ sẽ có chúng khác nhau). Các URI (ở dạng ProgramSelector) khác nhau giữa các kênh thô và chương trình được tìm thấy trong hầu hết các trường hợp (ngoại trừ FM không có RDS), nhưng hầu hết giống nhau giữa các chương trình được tìm thấy và chương trình yêu thích (ví dụ: ngoại trừ khi AF được cập nhật).

    Việc có các mediaId khác nhau cho các mục nhập từ các loại danh sách khác nhau giúp bạn có thể thực hiện các hành động khác nhau đối với chúng. Bạn có thể duyệt qua danh sách Mục ưa thích hoặc danh sách Tất cả chương trình trên onSkipToNext , tùy thuộc vào thư mục của MediaItem được chọn gần đây (xem MediaSession ).

    Hành động điều chỉnh đặc biệt

    Danh sách chương trình cho phép người dùng dò đến một đài cụ thể nhưng không cho phép người dùng thực hiện các yêu cầu chung như "Dò kênh FM", điều này có thể dẫn đến việc dò đến đài đã nghe gần đây trên băng tần FM.

    Để hỗ trợ những hành động như vậy, một số thư mục cấp cao nhất có bộ cờ FLAG_PLAYABLE (cùng với FLAG_BROWSABLE cho các thư mục).

    Hoạt động Giai điệu để Cách phát hành
    Phát đài Bất kỳ kênh phát thanh nào startService(ACTION_PLAY_BROADCASTRADIO)

    hoặc

    playFromMediaId(MediaBrowser. getRoot() )
    Phát FM Bất kỳ kênh FM nào Phát từ mediaId của băng tần FM.

    Việc xác định chương trình nào để điều chỉnh là tùy thuộc vào ứng dụng. Đây thường là kênh được điều chỉnh gần đây nhất trong danh sách nhất định. Để biết chi tiết về ACTION_PLAY_BROADCASTRADIO , hãy xem Ý định chơi chung .

    Khám phá và kết nối dịch vụ

    PackageManager có thể trực tiếp tìm thấy cây radio phát sóng phục vụ MediaBrowserService. Để làm như vậy, hãy gọi resolveService với mục đích ACTION_PLAY_BROADCASTRADIO (xem Ý định chơi chung ) và cờ MATCH_SYSTEM_ONLY . Để tìm tất cả các dịch vụ phục vụ radio (có thể có nhiều dịch vụ; ví dụ: tách AM/FM và vệ tinh), hãy sử dụng queryIntentServices .

    Dịch vụ đã giải quyết cũng xử lý mục đích liên kết android.media.browse.MediaBrowserService . Điều này đã được xác minh với GTS.

    Để kết nối với MediaBrowserService đã chọn, hãy tạo phiên bản MediaBrowser cho một thành phần dịch vụ nhất định và connect . Sau khi thiết lập kết nối, bạn có thể lấy mã điều khiển MediaSession thông qua getSessionToken .

    Ứng dụng Radio có thể hạn chế các gói ứng dụng khách được phép kết nối khi triển khai dịch vụ onGetRoot của họ. Ứng dụng phải cho phép các ứng dụng hệ thống kết nối mà không cần đưa vào danh sách trắng. Để biết chi tiết về danh sách trắng, hãy xem Chấp nhận gói ứng dụng và chữ ký Trợ lý .

    Nếu ứng dụng dành riêng cho nguồn (ví dụ: ứng dụng radio) được cài đặt trên một thiết bị không có hỗ trợ nguồn như vậy thì ứng dụng đó sẽ vẫn tự quảng cáo là đang xử lý mục đích ACTION_PLAY_BROADCASTRADIO , nhưng cây MediaBrowser của nó sẽ không chứa các thẻ dành riêng cho radio. Do đó, khách hàng sẵn sàng kiểm tra xem một nguồn nhất định có sẵn trên thiết bị hay không, phải:

    1. Khám phá dịch vụ radio (gọi resolveService cho ACTION_PLAY_BROADCASTRADIO ).
    2. Tạo MediaBrowser và sau đó kết nối với nó.
    3. Xác định sự hiện diện của MediaItem bằng EXTRA_BCRADIO_FOLDER_TYPE bổ sung.

    Lưu ý: Trong hầu hết các trường hợp, máy khách phải quét tất cả các cây MediaBrowser có sẵn để phát hiện tất cả các nguồn có sẵn cho một thiết bị nhất định.

    Tên ban nhạc

    Danh sách ban nhạc được biểu thị bằng một tập hợp các thư mục cấp cao nhất với thẻ loại thư mục được đặt thành BCRADIO_FOLDER_TYPE_BAND . Tiêu đề của MediaItem là các chuỗi được bản địa hóa đại diện cho tên ban nhạc. Trong hầu hết các trường hợp, nó sẽ giống với bản dịch tiếng Anh, nhưng khách hàng không thể phụ thuộc vào giả định đó.

    Để cung cấp cơ chế ổn định cho việc tra cứu các băng tần nhất định, một thẻ bổ sung được thêm vào cho các thư mục băng tần, EXTRA_BCRADIO_BAND_NAME_EN . Đây là tên chưa được bản địa hóa của ban nhạc và chỉ có thể lấy một trong các giá trị được xác định trước sau:

    • AM
    • FM
    • DAB

    Nếu ban nhạc không có trong danh sách này thì không nên đặt thẻ tên ban nhạc. Tuy nhiên, nếu ban nhạc có trong danh sách thì nó phải được gắn thẻ. Đài HD không liệt kê các băng tần riêng biệt vì nó sử dụng cùng một phương tiện cơ bản như AM/FM.

    Ý định chơi chung

    Mỗi ứng dụng dành riêng để phát nguồn nhất định (như radio hoặc CD) phải xử lý mục đích phát chung để bắt đầu phát một số nội dung có thể từ trạng thái không hoạt động (ví dụ: sau khi khởi động). Ứng dụng có quyền lựa chọn nội dung để phát nhưng thường là chương trình radio hoặc bản nhạc CD được phát gần đây. Có một mục đích riêng được xác định cho từng nguồn âm thanh:

    • android.car.intent.action.PLAY_BROADCASTRADIO
    • android.car.intent.action.PLAY_AUDIOCD : CD-DA hoặc CD-Text
    • android.car.intent.action.PLAY_DATADISC : Đĩa dữ liệu quang như CD/DVD, nhưng không phải CD-DA (có thể là CD Chế độ hỗn hợp)
    • android.car.intent.action.PLAY_AUX : Không chỉ định cổng Aux nào
    • android.car.intent.action.PLAY_BLUETOOTH
    • android.car.intent.action.PLAY_USB : Không chỉ định thiết bị USB nào
    • android.car.intent.action.PLAY_LOCAL : Bộ nhớ phương tiện cục bộ (đèn flash tích hợp)

    Ý định được chọn để sử dụng cho lệnh phát chung vì chúng giải quyết hai vấn đề cùng một lúc: chính lệnh phát chung và khám phá dịch vụ. Lợi ích bổ sung của việc có mục đích như vậy là khả năng thực hiện hành động đơn giản như vậy mà không cần mở phiên MediaBrowser.

    Khám phá dịch vụ thực sự là vấn đề quan trọng hơn được giải quyết bằng những ý định này. Quy trình khám phá dịch vụ theo cách này rất dễ dàng và rõ ràng (xem Khám phá và kết nối dịch vụ ).

    Để làm cho việc triển khai một số ứng dụng khách trở nên dễ dàng hơn, có một cách khác để phát lệnh Play như vậy (điều này cũng phải được ứng dụng radio triển khai): phát hành playFromMediaId với rootId của nút gốc (được sử dụng làm mediaId). Mặc dù nút gốc không có nghĩa là có thể phát được, nhưng rootId của nó là một chuỗi tùy ý có thể được tạo thành để có thể sử dụng được dưới dạng mediaId. Tuy nhiên, khách hàng không bắt buộc phải hiểu sắc thái này.

    Bộ chọn chương trình

    Mặc dù mediaId đủ để chọn một kênh từ MediaBrowserService nhưng nó sẽ bị ràng buộc với một phiên và không nhất quán giữa các nhà cung cấp. Trong một số trường hợp, máy khách có thể cần một con trỏ tuyệt đối (chẳng hạn như tần số tuyệt đối) để duy trì nó giữa các phiên và thiết bị.

    Trong thời đại phát sóng radio kỹ thuật số, tần số trần là không đủ để dò được một đài cụ thể. Do đó, hãy sử dụng ProgramSelector để dò sang kênh analog hoặc kỹ thuật số. ProgramSelector bao gồm hai phần:

    • Định danh chính. Mã nhận dạng duy nhất và ổn định cho một đài phát thanh nhất định, không thay đổi nhưng có thể không đủ để bắt sóng đài đó. Ví dụ: mã RDS PI, có thể được dịch sang dấu hiệu cuộc gọi ở Hoa Kỳ.
    • Các định danh phụ. Các mã định danh bổ sung hữu ích cho việc dò kênh đó (ví dụ: tần số), có thể bao gồm các mã định danh từ các công nghệ vô tuyến khác. Ví dụ: trạm DAB có thể có dự phòng phát sóng analog.

    Để cho phép ProgramSelector phù hợp với giải pháp dựa trên MediaBrowser - hoặc MediaSession , hãy xác định lược đồ URI để tuần tự hóa nó. Lược đồ được định nghĩa như sau:

    broadcastradio://program/<primary ID type>/<primary ID>?
    <secondary ID type>=<secondary ID>&<secondary ID type>=<secondary ID>
    

    Trong ví dụ này, phần Mã định danh phụ (sau dấu chấm hỏi ( ? )) là tùy chọn và có thể bị xóa để cung cấp mã định danh ổn định để sử dụng làm mediaId . Ví dụ:

    • broadcastradio://program/RDS_PI/1234?AMFM_FREQUENCY=88500&AMFM_FREQUENCY=103300
    • broadcastradio://program/AMFM_FREQUENCY/102100
    • broadcastradio://program/DAB_SID_EXT/14895264?RDS_PI=1234

    Phần quyền hạn (máy chủ AKA) của program cung cấp một số chỗ cho việc mở rộng chương trình trong tương lai. Các chuỗi loại mã định danh được chỉ định chính xác làm tên của chúng trong định nghĩa HAL 2.x của IdentifierType và định dạng giá trị là số thập phân hoặc thập lục phân (có tiền tố 0x ).

    Tất cả số nhận dạng dành riêng cho nhà cung cấp đều được biểu thị bằng tiền tố VENDOR_ . Ví dụ: VENDOR_0 cho VENDOR_STARTVENDOR_1 cho VENDOR_START cộng 1. Các URI như vậy dành riêng cho phần cứng vô tuyến nơi chúng được tạo ra và không thể chuyển giữa các thiết bị do các OEM khác nhau sản xuất.

    Các URI này phải được gán cho từng MediaItem trong thư mục radio cấp cao nhất. Ngoài ra, MediaSession phải hỗ trợ cả playFromMediaIdplayFromUri . Tuy nhiên, URI chủ yếu nhằm mục đích trích xuất siêu dữ liệu vô tuyến (chẳng hạn như tần số FM) và lưu trữ liên tục. Không có gì đảm bảo URI sẽ có sẵn cho tất cả các mục phương tiện (ví dụ: khi loại ID chính chưa được khung hỗ trợ). Mặt khác, Media ID luôn hoạt động. Khách hàng không nên sử dụng URI để chọn các mục từ phiên MediaBrowser hiện tại. Thay vào đó, hãy sử dụng playFromMediaId . Điều đó có nghĩa là nó không phải là tùy chọn đối với ứng dụng phân phát và các URI bị thiếu sẽ được dành riêng cho các trường hợp chính đáng.

    Thiết kế ban đầu sử dụng một dấu hai chấm thay vì chuỗi :// sau phần lược đồ. Tuy nhiên, cái trước không được android.net.Uri hỗ trợ cho các tham chiếu URI phân cấp tuyệt đối.

    Các loại nguồn khác

    Các nguồn âm thanh khác có thể được xử lý tương tự. Ví dụ: đầu vào phụ và đầu phát Audio CD.

    Một ứng dụng có thể phục vụ nhiều loại nguồn. Trong những trường hợp như vậy, bạn nên tạo một MediaBrowserService riêng cho từng loại nguồn. Ngay cả khi thiết lập có nhiều nguồn phân phối/MediaBrowserServices, bạn nên có một MediaSession duy nhất trong một ứng dụng.

    CD âm thanh

    Tương tự như Audio CD ở chỗ ứng dụng phục vụ các đĩa như vậy sẽ hiển thị MediaBrowser với một mục nhập có thể duyệt được (hoặc nhiều hơn, nếu hệ thống có bộ đổi CD), do đó sẽ chứa tất cả các bản nhạc của một CD nhất định. Nếu hệ thống không có kiến ​​thức về các bản nhạc trên mỗi đĩa CD (ví dụ: khi tất cả các đĩa được đưa vào hộp mực cùng một lúc và nó không đọc được tất cả), thì MediaItem cho toàn bộ đĩa sẽ chỉ là PLAYABLE , không phải BROWSABLE cộng với PLAYABLE . Nếu không có đĩa trong một vị trí nhất định, mục đó sẽ không PLAYABLE cũng như KHÔNG BROWSABLE (nhưng mỗi vị trí phải luôn có trong cây).

    Cấu trúc cây CD âm thanh
    Hình 3. Cấu trúc cây CD âm thanh

    Các mục này sẽ được đánh dấu theo cách tương tự như các thư mục radio phát sóng; chúng sẽ chứa các trường bổ sung bổ sung được xác định trong API MediaDescription:

    • EXTRA_CD_TRACK : Đối với mỗi MediaItem trên Audio CD, số bản nhạc dựa trên 1.
    • EXTRA_CD_DISK : số đĩa dựa trên 1.

    Đối với hệ thống hỗ trợ Văn bản CD và đĩa tương thích, MediaItem cấp cao nhất sẽ có tiêu đề của đĩa. Tương tự, MediaItems cho các bản nhạc sẽ có tiêu đề của bản nhạc.

    Đầu vào phụ

    Ứng dụng phục vụ đầu vào phụ trợ sẽ hiển thị cây MediaBrowser với một mục nhập duy nhất (hoặc nhiều hơn, khi có nhiều cổng) đại diện cho cổng vào Aux. MediaSession tương ứng lấy mediaId của nó và chuyển sang nguồn đó sau khi nhận được yêu cầu playFromMediaId .

    Cấu trúc cây Aux
    Hình 4. Cấu trúc cây Aux

    Mỗi mục nhập AV MediaItem sẽ có một trường bổ sung EXTRA_AUX_PORT_NAME được đặt thành tên cổng không được bản địa hóa mà không có cụm từ "AUX". Ví dụ: "AUX 1" sẽ được đặt thành "1", "AUX front" thành "front" và "AUX" thành một chuỗi trống. Ở các ngôn ngữ không phải tiếng Anh, thẻ tên sẽ giữ nguyên chuỗi tiếng Anh. Không có khả năng đối với EXTRA_BCRADIO_BAND_NAME_EN , các giá trị được xác định bằng OEM và không bị giới hạn trong danh sách được xác định trước.

    Nếu phần cứng có thể phát hiện các thiết bị được kết nối với cổng AUX, phần cứng sẽ đánh dấu MediaItem là PLAYABLE , chỉ khi đầu vào được kết nối. Phần cứng vẫn nên được liệt kê (nhưng không PLAYABLE ) nếu không có gì được kết nối với cổng này. Nếu phần cứng không có khả năng như vậy, MediaItem phải luôn luôn có PLAYABLE .

    Các trường bổ sung

    Xác định các trường sau:

    • EXTRA_CD_TRACK = "android.media.extra.CD_TRACK"
    • EXTRA_CD_DISK = "android.media.extra.CD_DISK"
    • EXTRA_AUX_PORT_NAME = "android.media.extra.AUX_PORT_NAME"

    Khách hàng cần xem xét các phương tiện truyền thông cấp cao nhất cho các yếu tố có trường EXTRA_CD_DISK hoặc EXTRA_AUX_PORT_NAME .

    Ví dụ chi tiết

    Các ví dụ sau đây đề cập đến cấu trúc cây MediaBrowser cho các loại nguồn là một phần của thiết kế này.

    Phát thanh phát thanh truyền thông RadioBrowserService (xử lý ACTION_PLAY_BROADCASTRADIO ):

    • Các trạm (có thể duyệt) EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_PROGRAMS
      • BBC One (có thể chơi) URI: broadcastradio://program/RDS_PI/1234?AMFM_FREQUENCY=90500
      • ABC 88.1 (có thể chơi) URI: broadcastradio://program/RDS_PI/5678?AMFM_FREQUENCY=88100
      • ABC 88.1 HD1 (có thể chơi) URI: broadcastradio://program/HD_STATION_ID_EXT/158241DEADBEEF?AMFM_FREQUENCY=88100&RDS_PI=5678
      • ABC 88.1 HD2 (có thể chơi) URI: broadcastradio://program/HD_STATION_ID_EXT/158242DEADBEFE
      • 90,5 fm (có thể chơi) - FM không có broadcastradio://program/AMFM_FREQUENCY/90500 :
      • broadcastradio://program/AMFM_FREQUENCY/620 sáng
      • BBC One (có thể chơi) URI: broadcastradio://program/DAB_SID_EXT/1E24102?RDS_PI=1234
    • EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_FAVORITES yêu thích (duyệt, có thể chơi
      • BBC One (có thể chơi) URI: broadcastradio://program/RDS_PI/1234?AMFM_FREQUENCY=101300
      • BBC Two (không thể chơi) URI: broadcastradio://program/RDS_PI/1300?AMFM_FREQUENCY=102100
    • AM (Duyệt, có thể chơi): EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_BANDEXTRA_BCRADIO_BAND_NAME_EN="AM"
      • broadcastradio://program/AMFM_FREQUENCY/530 sáng
      • 540 AM (có thể chơi) URI: broadcastradio://program/AMFM_FREQUENCY/540
      • broadcastradio://program/AMFM_FREQUENCY/550 sáng
    • Fm (có thể duyệt, có thể chơi): EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_BANDEXTRA_BCRADIO_BAND_NAME_EN="FM"
      • 87.7 FM (có thể chơi) URI: broadcastradio://program/AMFM_FREQUENCY/87700
      • 87.9 FM (có thể chơi) URI: broadcastradio://program/AMFM_FREQUENCY/87900
      • 88.1 FM (có thể chơi) URI: broadcastradio://program/AMFM_FREQUENCY/88100
    • Dab (có thể chơi): EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_BANDEXTRA_BCRADIO_BAND_NAME_EN="DAB"

    Audio CD MediaBrowserService (xử lý ACTION_PLAY_AUDIOCD ):

    • Đĩa 1 (có thể chơi) EXTRA_CD_DISK=1
    • Đĩa 2 (có thể duyệt, có thể chơi) EXTRA_CD_DISK=2
      • Track 1 (có thể chơi) EXTRA_CD_TRACK=1
      • Track 2 (có thể chơi) EXTRA_CD_TRACK=2
    • CD nhạc của tôi (có thể duyệt, có thể chơi) EXTRA_CD_DISK=3
      • Tất cả một mình (có thể chơi) EXTRA_CD_TRACK=1
      • Reise, Reise (có thể chơi) EXTRA_CD_TRACK=2
    • Khe trống 4 (không thể chơi) EXTRA_CD_DISK=4

    AUX MediaBrowserService (tay cầm ACTION_PLAY_AUX ):

    • AUX FRONT (có thể chơi) EXTRA_AUX_PORT_NAME="front"
    • AUX phía sau (có thể chơi) EXTRA_AUX_PORT_NAME="rear"