تشرح هذه الصفحة كيفية تنفيذ الراديو على مستوى الأجهزة والبرامج.
- توضح مكونات النظام مجموعة تكنولوجيا الراديو وتصفها.
- توفر طبقة تجريد أجهزة راديو البث (HAL) هياكل البيانات والواجهات لمصنعي المعدات الأصلية لتنفيذ راديو البث مثل AM/FM وراديو البث الصوتي الرقمي (DAB) على مستوى الأجهزة.
- يعتمد تنفيذ التحكم في الراديو على
MediaSession
وMediaBrowse
، اللذين يمكّنان تطبيقات الوسائط والمساعد الصوتي من التحكم في الراديو. بالإضافة إلى المحتوى المتوفر أدناه، راجع إنشاء تطبيقات الوسائط للسيارات .
مكونات النظام
تتضمن حزمة راديو البث المكونات التالية.
التطبيق المرجعي الراديو
للحصول على تفاصيل حول كيفية تنفيذ التحكم اللاسلكي، راجع تنفيذ التحكم اللاسلكي .
يعد نموذج تطبيق راديو Java ( packages/apps/Car/Radio
) بمثابة تطبيق مرجعي. عندما تبدأ خدمة التطبيق، فإنها تطلب من مدير الراديو فتح موالف الراديو. بعد ذلك، يمكن للتطبيق إرسال طلبات إلى موالف الراديو، مثل ضبط محطة راديو معينة، أو تردد معين، أو البحث عن محطة الراديو التالية المتاحة. يتلقى التطبيق تحديثات من Radio Manager وRadio Tuner في الراديو، مثل معلومات البرنامج الحالية وقوائم برامج الراديو والتكوينات والمعلمات المحددة بواسطة البائع. يدعم تطبيق الراديو المرجعي راديو AM وFM فقط. يمكن لمصنعي المعدات الأصلية تعديل تطبيق الراديو أو استبداله حسب الرغبة.
مدير الراديو
عندما يطلب التطبيق من Radio Manager فتح موالف، فإن مدير الراديو ( frameworks/base/core/java/android/hardware/radio/RadioManager.java
) يطلب من خدمة بث الراديو فتح جلسة موالف ثم تغليف الجلسة في ملف موالف الراديو ( frameworks/base/core/java/android/hardware/radio/RadioTuner.java
)، والذي يتم إرجاعه إلى التطبيق. يحدد موالف الراديو واجهات برمجة التطبيقات (مثل التوليف والخطوة والإلغاء) التي يمكن استدعاؤها من تطبيقات الراديو وإرسال الطلبات إلى خدمة بث الراديو. تقوم أساليب رد الاتصال ( RadioTuner.Callback
) المحددة في Radio Tuner بإرسال تحديثات حول بث الراديو HAL، مثل معلومات البرنامج الحالية وقوائم البرامج والمعلمات المحددة من قبل البائع، من خدمة بث الراديو إلى التطبيقات.
خدمة البث الإذاعي
خدمة البث الإذاعي ( frameworks/base/services/core/java/com/android/server/broadcastradio
) هي خدمة العملاء لـ Broadcast Radio HAL. تقوم خدمة البث الإذاعي بتنسيق مديري الراديو المتعددين مع وحدات HAL للبث الإذاعي. تدعم خدمة البث الإذاعي لغة تعريف واجهة HAL (HIDL) ولغة تعريف واجهة Android (AIDL) لبث الراديو HALs. ترتبط خدمة البث الإذاعي بـ AIDL HAL عند وجود أي خدمة AIDL HAL؛ وبخلاف ذلك، ترتبط الخدمة بـ HIDL HAL. تقوم خدمة البث الإذاعي بإنشاء وحدة راديو لكل مثيل HAL متاح (مثل AM وFM وDAB).
يمكن لكل مدير راديو أن يطلب من خدمة البث الإذاعي إنشاء جلسة موالف على وحدة الراديو المقابلة، بناءً على نوع الراديو. يمكن لكل جلسة موالف استدعاء أساليب، مثل التوليف والخطوة والإلغاء (المحددة في واجهات HAL) لتنفيذ العمليات على مثيل HAL للبث الراديوي المقابل. عندما تتلقى جلسة موالف واحدة رد اتصال من مثيل HAL على تحديث HAL، مثل معلومات البرنامج الحالية وقائمة البرامج وإشارات التكوين ومعلمات البائع، يتم إرسال ردود الاتصال حول التحديث إلى جميع موالفات الراديو المرتبطة بنفس وحدة الراديو.
بث راديو هال
لمعرفة المزيد حول واجهات HIDL وAIDL الخاصة ببث الراديو والاختلافات بينهما، راجع واجهة بث راديو HAL .
طبقة تجريد أجهزة الراديو
تصف الأقسام التالية كيفية العمل مع طبقة تجريد الأجهزة (HAL) لتنفيذ البث الإذاعي.
واجهة البث الإذاعي HAL
يوفر راديو البث HAL هياكل البيانات والواجهات على مستوى الأجهزة لتنفيذ البث الراديوي، مثل راديو AM/FM وراديو DAB.
واجهات HIDL 2.0 وAIDL
يستخدم راديو البث HAL الواجهات الموضحة في الأقسام التالية.
مستمع اعلان
IAnnouncementListener
هي واجهة رد الاتصال لمستمع الإعلانات، والتي يمكن تسجيلها على راديو البث HAL لتلقي الإعلانات. تحتوي الواجهة على الطرق التالية:
IAnnouncementListener | ||
---|---|---|
الوصف: يتم الاتصال به كلما تغيرت قائمة الإعلانات. | ||
هيدل 2.0 | oneway onListUpdated(vec<Announcement> announcements) | |
AIDL | oneway void onListUpdated(in Announcement[] announcements) |
إغلاق المقبض
ICloseHandle
هو مقبض الإغلاق العام لإزالة رد الاتصال الذي لا يحتاج إلى واجهة نشطة.
ICloseHandle | ||
---|---|---|
الوصف: أغلق المقبض. | ||
هيدل 2.0 | close() | |
AIDL | void close() |
واجهة رد الاتصال
ITunerCallback
هي واجهة رد الاتصال التي يستدعيها راديو البث HAL لإرسال التحديثات إلى خدمة عملاء HAL.
ITunerCallback | ||
---|---|---|
الوصف: يتم استدعاؤه بواسطة HAL عند فشل عملية الضبط (التوليف أو البحث (في AIDL) أو المسح الضوئي (في HIDL) ونجاح الخطوة) بشكل غير متزامن. | ||
هيدل 2.0 | oneway onCurrentProgramInfoChanged(ProgramInfo info) | |
AIDL | void onCurrentProgramInfoChanged(in ProgramInfo info) | |
الوصف: يتم استدعاؤه عند الضبط أو البحث (في AIDL) أو المسح الضوئي (في HIDL) أو نجاح الخطوة. | ||
هيدل 2.0 | oneway onTuneFailed(Result result, ProgramSelector selector) | |
AIDL | void onTuneFailed(in Result result, in ProgramSelector selector) | |
الوصف: يتم استدعاؤه عند الضبط أو البحث (في AIDL) أو المسح الضوئي (في HIDL) أو نجاح الخطوة. | ||
هيدل 2.0 | oneway onCurrentProgramInfoChanged(ProgramInfo info) | |
AIDL | void onCurrentProgramInfoChanged(in ProgramInfo info) | |
الوصف: يتم الاتصال به عند تحديث قائمة البرامج؛ يجب أن يقتصر حجم كل قطعة على 500 كيلو بايت. | ||
هيدل 2.0 | oneway onProgramListUpdated(ProgramListChunk chunk) | |
AIDL | oneway onProgramListUpdated(ProgramListChunk chunk) | |
الوصف: يتم الاتصال به عند توصيل الهوائي أو فصله. | ||
هيدل 2.0 | oneway onAntennaStateChange(bool connected) | |
AIDL | void onCurrentProgramInfoChanged(in ProgramInfo info) | |
الوصف: يتم استدعاؤه عندما يتم تحديث قيم المعلمات الخاصة بالمورد داخليًا في HAL (لا ينبغي استدعاؤه بعد استدعاء setParameters بواسطة عميل HAL). | ||
هيدل 2.0 | oneway onParametersUpdated(vec<VendorKeyValue> parameters) | |
AIDL | void onParametersUpdated(in VendorKeyValue[] parameters) | |
الوصف: الجديد في AIDL. يتم استدعاؤه عندما يتم تحديث علامة التكوين داخليًا في HAL (لا ينبغي استدعاؤه بعد استدعاء setConfigFlag بواسطة عميل HAL). | ||
هيدل 2.0 | غير قابل للتطبيق. | |
AIDL | void onConfigFlagUpdated(in ConfigFlag flag, in boolean value) |
واجهة البث الإذاعي الأساسية HAL
IBroadcastRadio
هي الواجهة الأساسية لبث الراديو HAL. في HIDL 2.0 HAL، استخدم واجهة ITunerSession
للموالف لاستدعاء العمليات. ومع ذلك، يكون موالف واحد نشطًا على الأكثر في وقت واحد (شريطة أن تحتوي كل مثيلات HAL للبث الراديوي على شريحة موالف واحدة فقط). تمت إزالة ITunerSession
من واجهات AIDL وتم نقل واجهاتها إلى IBroadcastRadio
.
IBroadcastRadio | ||
---|---|---|
الوصف: احصل على وصف الوحدة وإمكانياتها. | ||
هيدل 2.0 | getProperties() generates (Properties properties) | |
AIDL | Properties getProperties() | |
الوصف: جلب تكوين منطقة AM/FM الحالي أو المحتمل. | ||
هيدل 2.0 | getAmFmRegionConfig(bool full) generates (Result result, AmFmRegionConfig config) | |
AIDL | AmFmRegionConfig getAmFmRegionConfig(bool full) | |
الوصف: جلب التكوين الحالي لمنطقة DAB. | ||
هيدل 2.0 | getDabRegionConfig() generates (Result result, vec<DabTableEntry> config) | |
AIDL | DabTableEntry[] getDabRegionConfig() | |
الوصف: الحصول على صورة من ذاكرة التخزين المؤقت لوحدة الراديو. في AIDL، يجب أن يكون حجم الصورة أقل من 1 ميجابايت بسبب وجود حد صارم على المخزن المؤقت لمعاملات الموثق. | ||
هيدل 2.0 | getImage(uint32_t id) generates (vec<uint8_t> image) | |
AIDL | byte[] getImage(in int id) | |
الوصف: يسجل مستمع الإعلان. | ||
هيدل 2.0 | registerAnnouncementListener(vec<AnnouncementType> enabled,IAnnouncementListener listener) generates (Result result, ICloseHandle closeHandle) | |
AIDL | ICloseHandle registerAnnouncementListener(in IAnnouncementListener listener, in AnnouncementType[] enabled) | |
وصف:
| ||
هيدل 2.0 | يُنشئ openSession(ITunerCallback callback) (Result result, ITunerSession session) | |
AIDL | void setTunerCallback(in ITunerCallback callback) | |
وصف:
| ||
هيدل 2.0 | close() | |
AIDL | unsetTunerCallback() | |
الوصف: يضبط برنامجًا محددًا. | ||
هيدل 2.0 | tune(ProgramSelector program) generates (Result result) | |
AIDL | void tune(in ProgramSelector program) | |
الوصف: يبحث عن البرنامج الصالح التالي على الهواء . لتجنب الارتباك في AIDL، تمت إعادة تسمية scan إلى seek . | ||
هيدل 2.0 | scan(bool directionUp, bool skipSubChannel) generates (Result result) | |
AIDL | void seek(in boolean directionUp, in boolean skipSubChannel) | |
الوصف: خطوات إلى القناة المجاورة التي قد لا يشغلها أي برنامج. | ||
هيدل 2.0 | step(bool directionUp) generates (Result result) | |
AIDL | void step(in boolean directionUp) | |
الوصف: يلغي عمليات التوليف المعلقة أو المسح الضوئي (في HIDL) أو البحث (في AIDL) أو العمليات المرحلية. | ||
هيدل 2.0 | cancel() | |
AIDL | void cancel() | |
الوصف: تطبيق عامل تصفية على قائمة البرامج وبدء إرسال تحديثات قائمة البرامج عبر رد الاتصال onProgramListUpdated . | ||
هيدل 2.0 | startProgramListUpdates(ProgramFilter filter) generates (Result result) | |
AIDL | void startProgramListUpdates(in ProgramFilter filter) | |
الوصف: توقف عن إرسال تحديثات قائمة البرامج. | ||
هيدل 2.0 | stopProgramListUpdates() | |
AIDL | void stopProgramListUpdates() | |
الوصف: جلب الإعداد الحالي لعلامة تكوين معينة. | ||
هيدل 2.0 | isConfigFlagSet(ConfigFlag flag) generates (Result result, bool value) | |
AIDL | boolean isConfigFlagSet(in ConfigFlag flag) | |
الوصف: يقوم بتعيين علامة التكوين المحددة. | ||
هيدل 2.0 | setConfigFlag(ConfigFlag flag, bool value) generates (Result result) | |
AIDL | void setConfigFlag(in ConfigFlag flag, boolean value) | |
الوصف: يعين قيم المعلمات الخاصة بالبائع. | ||
هيدل 2.0 | setParameters(vec<VendorKeyValue> parameters) يولد ، (vec<VendorKeyValue> results) | |
AIDL | VendorKeyValue[] setParameters(in VendorKeyValue[] parameters) | |
الوصف: استرداد قيم المعلمات الخاصة بالبائع. | ||
هيدل 2.0 | getParameters(vec<string> keys) generates (vec<VendorKeyValue> parameters) | |
AIDL | VendorKeyValue[] getParameters(in String[] keys) |
توضيحات الواجهة
السلوك غير المتزامن
نظرًا لأن كل عملية ضبط (على سبيل المثال، التوليف والمسح الضوئي (في HIDL) أو البحث (في AIDL) والخطوة) قد تستغرق وقتًا طويلاً ويجب ألا يتم حظر مؤشر الترابط لفترة طويلة، يجب أن تقوم العملية بجدولة العمليات التي تستغرق وقتًا طويلاً ليحدث لاحقًا ويعيد الحالة أو النتيجة بسرعة. بالتفصيل، ينبغي لكل عملية:
- قم بإلغاء كافة عمليات الضبط المعلقة.
- تحقق مما إذا كان من الممكن معالجة العملية بناءً على مدخلات الطريقة وحالة الموالف.
- قم بجدولة مهمة الضبط ثم قم بإرجاع
Result
(في HIDL) أوstatus
(في AIDL) على الفور. إذا كانتResult
أوstatus
علىOK
، فيجب استدعاء رد اتصال الموالفtuneFailed
أوcurrentProgramInfoChanged
عند فشل مهمة الضبط (على سبيل المثال، بسبب انتهاء المهلة) أو اكتمالها.
وبالمثل، يقوم startProgramListUpdates
أيضًا بجدولة المهمة التي تستغرق وقتًا طويلاً وهي تحديث قائمة البرامج ليتم إجراؤها لاحقًا ولإرجاع الحالة أو النتيجة بسرعة. تقوم الطريقة أولاً بإلغاء طلبات التحديث المعلقة ثم تقوم بجدولة مهمة التحديث وإرجاع النتيجة بسرعة.
حالة السباق
بسبب السلوك غير المتزامن لعمليات الضبط (على سبيل المثال، التوليف والمسح الضوئي (في HIDL) أو البحث (في AIDL) والخطوة)، توجد حالة سباق بين إلغاء العملية وعمليات الضبط. إذا تم استدعاء cancel
بعد إكمال HAL لعملية ضبط وقبل اكتمال رد الاتصال، فيمكن تجاهل الإلغاء ويجب إكمال رد الاتصال واستلامه بواسطة عميل HAL.
وبالمثل، إذا تم استدعاء stopProgramListUpdates
بعد اكتمال HAL لتحديث قائمة البرامج وقبل اكتمال رد الاتصال onCurrentProgramInfoChanged
، فيمكن تجاهل stopProgramListUpdates
ويجب إكمال رد الاتصال.
الحد الأقصى لحجم البيانات
نظرًا لوجود حد صارم في المخزن المؤقت لمعاملات الموثق، يتم توضيح حد البيانات لبعض طرق الواجهة التي تمرر البيانات ذات الحجم الكبير المحتمل في AIDL HAL.
- يتطلب
getImage
أن يتم إرجاع الصورة بأقل من 1 ميغابايت. - يتطلب
onProgramListUpdate
أن يكون حجم كلchunk
أقل من 500 كيلو بايت. يجب تقسيم قوائم البرامج الأكبر حجمًا بواسطة تطبيق HAL إلى أجزاء متعددة وإرسالها عبر عمليات رد اتصال متعددة.
التغييرات في هياكل البيانات AIDL HAL
بالإضافة إلى التغييرات في الواجهات، تم تطبيق هذه التغييرات على هياكل البيانات المحددة في البث الإذاعي AIDL HAL، الذي يستفيد من AIDL.
- تتم إزالة التعداد
Constant
في AIDL ويتم تعريفه على أنه const int فيIBroadcastRadio
. وفي الوقت نفسه، تمت إعادة تسميةANTENNA_DISCONNECTED_TIMEOUT_MS
إلىANTENNA_STATE_CHANGE_TIMEOUT_MS
. تمت إضافة const intTUNER_TIMEOUT_MS
جديد. يجب إكمال جميع عمليات الضبط والبحث والخطوة خلال هذا الوقت. - تتم إزالة Enum
RDS
وDeemphasis
في AIDL ويتم تعريفهما على أنهما const int فيAmFmRegionConfig
. في المقابل، يتم تعريف كل منfmDeemphasis
وfmRds
فيProgramInfo
كـ int، وهي نتيجة حسابية صغيرة للأعلام المعنية. وفي الوقت نفسه، تمت إعادة تسميةD50
وD75
إلىDEEMPHASIS_D50
وDEEMPHASIS_D75
على التوالي. - تتم إزالة Enum
ProgramInfoFlags
في AIDL ويتم تعريفها على أنها const int فيProgramInfo
مع إضافة البادئةFLAG_
. في المقابل، يتم تعريفinfoFlags
فيProgramInfo
كـ int، وهي نتيجة حسابية صغيرة للأعلام. تمت إعادة تسميةTUNED
أيضًا إلىFLAG_TUNABLE
، لوصف تعريفها الذي يمكن ضبط المحطة عليه بشكل أفضل. - في
AmFmBandRange
، تمت إعادة تسميةscanSpacing
إلىseekSpacing
، حيث تمت إعادة تسميةscan
seek
في AIDL. - منذ تقديم مفهوم الاتحاد في AIDL، لم تعد
MetadataKey
وبياناتMetadata
المحددة في HIDL HAL مستخدمة. يتم تعريفMetadata
لاتحاد AIDL في AIDL HAL. كل قيمة تعداد كانت موجودة سابقًا فيMetadataKey
أصبحت الآن حقلاً فيMetadata
بنوع السلسلة أو int، اعتمادًا على تعريفاتها.
تنفيذ التحكم بالراديو
يعتمد تنفيذ التحكم في الراديو على MediaSession
و MediaBrowse
، اللذين يمكّنان تطبيقات الوسائط والمساعد الصوتي من التحكم في الراديو. لمزيد من المعلومات، راجع إنشاء تطبيقات الوسائط للسيارات على موقع Developer.android.com.
يتم توفير تطبيق شجرة تصفح الوسائط في مكتبة دعم راديو السيارة في packages/apps/Car/libs
. تحتوي هذه المكتبة أيضًا على امتدادات ProgramSelector للتحويل من وإلى URI. من المستحسن أن تستخدم تطبيقات الراديو هذه المكتبة لإنشاء شجرة التصفح المرتبطة بها.
محوّل مصدر الوسائط
لتوفير انتقال سلس بين الراديو والتطبيقات الأخرى المعروضة في الوسائط، تحتوي مكتبة car-media-common على فئات يجب دمجها في تطبيق الراديو. يمكن تضمين MediaAppSelectorWidget
في ملف XML لتطبيق الراديو (الرمز والقائمة المنسدلة المستخدمة في الوسائط المرجعية وتطبيقات الراديو):
<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" />
تقوم هذه الأداة بتشغيل AppSelectionFragment
، الذي يعرض قائمة بمصادر الوسائط التي يمكن التبديل إليها. إذا كنت ترغب في واجهة مستخدم غير تلك المتوفرة، فيمكنك إنشاء عنصر واجهة مستخدم مخصص لتشغيل AppSelectionFragment
عندما يجب عرض المحول.
AppSelectionFragment newFragment = AppSelectionFragment.create(widget, packageName, fullScreen); newFragment.show(mActivity.getSupportFragmentManager(), null);
يتم توفير نموذج للتنفيذ في تطبيق الراديو المرجعي، الموجود في packages/apps/Car/Radio
.
مواصفات التحكم التفصيلية
توفر واجهة MediaSession
(من خلال MediaSession.Callback
) آليات التحكم لبرنامج الراديو الذي يتم تشغيله حاليًا:
-
onPlay
،onStop
. (إلغاء) كتم صوت تشغيل الراديو. -
onPause
. توقف مؤقت مؤقت (إذا كان مدعومًا). -
onPlayFromMediaId
. قم بتشغيل أي محتوى من مجلد المستوى الأعلى. على سبيل المثال، "تشغيل FM" أو "تشغيل الراديو". -
onPlayFromUri
. تشغيل تردد معين. على سبيل المثال، "تشغيل 88.5 FM." -
onSkipToNext
،onSkipToPrevious
. قم بالضبط على المحطة التالية أو السابقة. -
onSetRating
. إضافة أو إزالة إلى أو من المفضلة.
يعرض MediaBrowser MediaItem القابل للضبط عبر ثلاثة أنواع من أدلة المستوى الأعلى:
- ( اختياري ) البرامج (المحطات). يتم استخدام هذا الوضع عادةً بواسطة أجهزة الراديو ذات الموالف المزدوج للإشارة إلى جميع محطات الراديو القابلة للضبط المتوفرة في موقع المستخدم.
- المفضلة. تمت إضافة برامج الراديو إلى قائمة المفضلة، وقد يكون بعضها غير متاح (خارج نطاق الاستقبال).
- قنوات الفرقة. جميع القنوات الممكنة فيزيائياً في المنطقة الحالية (87.9، 88.1، 88.3، 88.5، 88.7، 88.9، 89.1 وهكذا). تحتوي كل فرقة على دليل منفصل للمستوى الأعلى.
كل عنصر في كل من هذه المجلدات (AM/FM/البرامج) هو MediaItem مع URI يمكن استخدامه مع MediaSession لضبطه. كل مجلد من مجلدات المستوى الأعلى (AM/FM/البرامج) عبارة عن عنصر MediaItem مزود بمعرف وسائط يمكن استخدامه مع MediaSession لتشغيل التشغيل ويعود ذلك إلى تقدير الشركة المصنّعة للمعدات الأصلية (OEM). على سبيل المثال، "Play FM" و"Play AM" و"Play Radio" كلها استعلامات راديو غير محددة تستخدم mediaId لإرسالها إلى تطبيق راديو OEM. الأمر متروك لتطبيق الراديو لتحديد ما سيتم تشغيله من الطلب العام ومعرف الوسائط.
MediaSession
نظرًا لعدم وجود مفهوم لإيقاف دفق البث مؤقتًا، فإن إجراءات التشغيل والإيقاف المؤقت والإيقاف لا تنطبق دائمًا على الراديو. مع الراديو، يرتبط إجراء الإيقاف بكتم صوت البث بينما يرتبط إجراء التشغيل بإزالة كتم الصوت.
توفر بعض موالفات الراديو (أو التطبيقات) القدرة على محاكاة إيقاف البث مؤقتًا عن طريق تخزين المحتوى مؤقتًا ثم تشغيله مرة أخرى لاحقًا. في مثل هذه الحالات، استخدم onPause
.
يهدف التشغيل من إجراءات mediaId وURI إلى ضبط محطة تم جلبها من واجهة MediaBrowser. mediaId عبارة عن سلسلة عشوائية يقدمها تطبيق الراديو لفرض قيمة فريدة (بحيث يشير معرف معين إلى عنصر واحد فقط) وقيمة ثابتة (بحيث يكون لعنصر معين نفس المعرف خلال الجلسة بأكملها) لتحديد محطة معينة . سيكون URI ذو مخطط محدد جيدًا. باختصار، نموذج URI من ProgramSelector. وفي حين أن هذا يحافظ على خاصية التفرد، فإنه ليس من الضروري أن يكون مستقرًا، على الرغم من أنه يمكن أن يتغير عندما تتحرك المحطة إلى تردد مختلف.
حسب التصميم، لا يتم استخدام onPlayFromSearch
. تقع على عاتق العميل (التطبيق المصاحب) مسؤولية تحديد نتيجة بحث من شجرة MediaBrowser. سيؤدي نقل هذه المسؤولية إلى تطبيق الراديو إلى زيادة التعقيد، ويتطلب عقودًا رسمية حول كيفية ظهور الاستعلامات المتسلسلة، ويؤدي إلى تجربة مستخدم غير متساوية على منصات الأجهزة المختلفة.
ملاحظة: لا يحتوي تطبيق الراديو على معلومات إضافية قد تكون مفيدة للبحث عن اسم محطة غير مكشوف للعميل من خلال واجهة MediaBrowser.
يعتمد التخطي إلى المحطة التالية أو السابقة على السياق الحالي:
- عند ضبط تطبيق ما على محطة من قائمة المفضلة، يمكن للتطبيق الانتقال إلى المحطة التالية من قائمة المفضلة.
- قد يؤدي الاستماع إلى محطة من قائمة البرامج إلى الضبط على المحطة التالية المتوفرة، مرتبة حسب رقم القناة.
- قد يؤدي الاستماع إلى قناة عشوائية إلى ضبط القناة الفعلية التالية، حتى في حالة عدم وجود إشارة بث.
يتعامل تطبيق الراديو مع هذه الإجراءات.
معالجة الأخطاء
لا توفر إجراءات TransportControls
(التشغيل والإيقاف والتالي) تعليقات حول نجاح الإجراء أم لا. الطريقة الوحيدة للإشارة إلى وجود خطأ هي ضبط حالة MediaSession على STATE_ERROR
مع ظهور رسالة خطأ.
يجب أن يتعامل تطبيق الراديو مع هذه الإجراءات ويقوم بتنفيذها أو تعيين حالة خطأ. إذا لم يكن تنفيذ أمر التشغيل فوريًا، فيجب تغيير حالة التشغيل إلى STATE_CONNECTING
(في حالة التوليف المباشر) أو STATE_SKIPPING_TO_PREVIOUS
أو NEXT
أثناء تنفيذ الأمر.
يجب على العميل مشاهدة PlaybackState
والتحقق من أن الجلسة غيرت البرنامج الحالي إلى ما تم طلبه أو تم إدخاله في حالة الخطأ. يجب ألا يتجاوز STATE_CONNECTING
30 ثانية. ومع ذلك، فإن التوليف المباشر لتردد AM/FM معين يجب أن يؤدي بشكل أسرع بكثير.
إضافة وإزالة المفضلة
تتمتع MediaSession بدعم التصنيف، والذي يمكن استخدامه للتحكم في المفضلة. يقوم onSetRating
الذي يتم استدعاؤه بتصنيف من النوع RATING_HEART
بإضافة أو إزالة المحطة التي تم ضبطها حاليًا إلى قائمة المفضلة أو منها.
على عكس الإعدادات المسبقة القديمة، يفترض هذا النموذج وجود قائمة مفضلة غير مرتبة وغير محدودة، عندما يتم تخصيص كل مفضلة محفوظة لفتحة رقمية (عادةً، من 1 إلى 6). ونتيجة لذلك، قد تكون الأنظمة المعتمدة مسبقًا غير متوافقة مع عملية onSetRating
.
تتمثل قيود MediaSession API في أنه يمكن إضافة أو إزالة المحطة التي تم ضبطها حاليًا فقط. على سبيل المثال، يجب تحديد العناصر أولاً قبل أن تتم إزالتها. وهذا مجرد قيد على عميل MediaBrowser، مثل التطبيق المصاحب. تطبيق الراديو ليس مقيدًا بالمثل. يكون هذا الجزء اختياريًا عندما لا يدعم التطبيق المفضلة.
متصفح الوسائط
للتعبير عن الترددات أو أسماء القنوات المادية (عندما يكون التوليف على قناة عشوائية مناسبًا لتقنية راديو معينة) صالحة لمنطقة معينة، يتم إدراج جميع القنوات (الترددات) الصالحة لكل نطاق. في منطقة الولايات المتحدة، يصل هذا إلى 101 قناة FM في نطاق 87.8 إلى 108.0 ميجا هرتز (باستخدام تباعد 0.2 ميجا هرتز) و117 قناة AM في نطاق 530 إلى 1700 كيلو هرتز (باستخدام تباعد 10 كيلو هرتز). نظرًا لأن الراديو عالي الدقة يستخدم نفس مساحة القناة، فلا يتم تقديمه بشكل منفصل.
قائمة برامج الراديو المتوفرة حاليًا مسطحة من حيث أنها لا تسمح بأنظمة العرض مثل التجميع حسب مجموعة البث الصوتي المباشر (DAB).
قد لا تكون الإدخالات الموجودة في القائمة المفضلة قابلة للضبط. على سبيل المثال، إذا كان برنامج معين خارج النطاق. قد يكتشف تطبيق الراديو أو لا يكتشف ما إذا كان من الممكن ضبط الإدخال مسبقًا. إذا كان الأمر كذلك، فقد لا يتم وضع علامة على الإدخال باعتباره قابلاً للتشغيل.
لتحديد مجلدات المستوى الأعلى، يتم تطبيق نفس الآلية التي تستخدمها تقنية Bluetooth. أي أن حزمة الإضافات لكائن MediaDescription
تحتوي على حقل خاص بالموالف تمامًا كما يفعل Bluetooth مع EXTRA_BT_FOLDER_TYPE
. في حالة البث الإذاعي، يؤدي ذلك إلى تحديد الحقول الجديدة التالية في واجهة برمجة التطبيقات العامة:
-
EXTRA_BCRADIO_FOLDER_TYPE = "android.media.extra.EXTRA_BCRADIO_FOLDER_TYPE"
. إحدى القيم التالية:-
BCRADIO_FOLDER_TYPE_PROGRAMS = 1
. البرامج المتوفرة حاليا. -
BCRADIO_FOLDER_TYPE_FAVORITES = 2
. المفضلة. -
BCRADIO_FOLDER_TYPE_BAND = 3
. جميع القنوات المادية لفرقة معينة.
ليست هناك حاجة لتحديد أي حقول بيانات تعريف مخصصة خاصة بالراديو، حيث أن جميع البيانات ذات الصلة تتناسب مع نظام
MediaBrowser.MediaItem
الحالي:- اسم البرنامج (RDS PS، اسم خدمة DAB).
MediaDescription.getTitle
. - تردد إف إم. URI (راجع ProgramSelector ) أو
MediaDescription.getTitle
(إذا كان الإدخال موجودًا في المجلدBROADCASTRADIO_FOLDER_TYPE_BAND
). - معرفات الراديو الخاصة (RDS PI، DAB SId). تم تحليل
MediaDescription.getMediaUri
إلى ProgramSelector.
عادةً، ليست هناك حاجة لجلب تردد FM لإدخال في البرنامج الحالي أو قائمة المفضلة (حيث يجب أن يعمل العميل على معرفات الوسائط). ومع ذلك، إذا ظهرت مثل هذه الحاجة (على سبيل المثال، لأغراض العرض)، فهي موجودة في URI ويمكن تحليلها إلى
ProgramSelector
. ومع ذلك، لا يوصى باستخدام معرف URI لتحديد العناصر ضمن الجلسة الحالية. لمزيد من التفاصيل، راجعProgramSelector
.لتجنب المشكلات المتعلقة بالأداء أو الموثق، يجب أن تدعم خدمة MediaBrowser ترقيم الصفحات:
-
EXTRA_PAGE
-
EXTRA_PAGE_SIZE
- معلمات إضافية
subscribe()
ملاحظة: افتراضيًا، يتم تنفيذ ترقيم الصفحات افتراضيًا في متغير
onLoadChildren()
دون معالجة الخيارات.قد تحتوي الإدخالات ذات الصلة من جميع أنواع القوائم (القنوات الأولية والبرامج الموجودة والمفضلة) على معرفات وسائط مختلفة (الأمر متروك لتطبيق الراديو؛ وستجعلها مكتبة الدعم مختلفة). تختلف معرفات URI (في نموذج ProgramSelector) بين القنوات الأولية والبرامج الموجودة في معظم الحالات (باستثناء FM بدون RDS)، ولكنها في الغالب هي نفسها بين البرامج الموجودة والمفضلة (باستثناء، على سبيل المثال، عند تحديث التركيز البؤري التلقائي).
إن وجود معرفات وسائط مختلفة للإدخالات من أنواع مختلفة من القوائم يجعل من الممكن اتخاذ إجراءات مختلفة عليها. يمكنك اجتياز قائمة المفضلة أو قائمة كافة البرامج في
onSkipToNext
، اعتمادًا على مجلدMediaItem
المحدد مؤخرًا (راجع MediaSession ).إجراءات لحن خاصة
تمكن قائمة البرامج المستخدمين من ضبط محطة معينة، ولكنها لا تسمح للمستخدمين بتقديم طلبات عامة مثل "Tune to FM"، مما قد يؤدي إلى ضبط محطة تم الاستماع إليها مؤخرًا على نطاق FM.
لدعم مثل هذه الإجراءات، تحتوي بعض أدلة المستوى الأعلى على مجموعة علامات
FLAG_PLAYABLE
(جنبًا إلى جنب معFLAG_BROWSABLE
للمجلدات).فعل نغمات ل كيفية إصدار تشغيل الراديو أي قناة إذاعية startService(ACTION_PLAY_BROADCASTRADIO)
أو
playFromMediaId(MediaBrowser. getRoot() )
تشغيل FM أي قناة FM قم بالتشغيل من mediaId
الخاص بنطاق FM.إن تحديد البرنامج الذي سيتم ضبطه يعود إلى التطبيق. عادةً ما تكون هذه هي القناة التي تم ضبطها مؤخرًا من القائمة المحددة. للحصول على تفاصيل حول
ACTION_PLAY_BROADCASTRADIO
، راجع أهداف التشغيل العامة .الاكتشاف والاتصال بالخدمة
يمكن
PackageManager
العثور مباشرة على شجرة راديو البث التي تخدم MediaBrowserService. للقيام بذلك، اتصل بـresolveService
بهدفACTION_PLAY_BROADCASTRADIO
(راجع أهداف التشغيل العامة ) وعلامةMATCH_SYSTEM_ONLY
. للعثور على جميع الخدمات التي تخدم الراديو (قد يكون هناك أكثر من خدمة واحدة؛ على سبيل المثال، AM/FM منفصل وقمر صناعي)، استخدمqueryIntentServices
.تتعامل الخدمة التي تم حلها مع غرض ربط
android.media.browse.MediaBrowserService
أيضًا. تم التحقق من ذلك باستخدام GTS.للاتصال بـ MediaBrowserService المحدد، قم بإنشاء مثيل
MediaBrowser
لمكون خدمة معين وقمconnect
. بعد إنشاء الاتصال، يمكن الحصول على مؤشر MediaSession عبرgetSessionToken
.يمكن لتطبيق الراديو تقييد حزم العملاء المسموح لها بالاتصال في تطبيق
onGetRoot
لخدمتهم. يجب أن يسمح التطبيق لتطبيقات النظام بالاتصال دون القائمة البيضاء. للحصول على تفاصيل حول القائمة البيضاء، راجع قبول حزمة تطبيق المساعد والتوقيع .إذا تم تثبيت التطبيق الخاص بالمصدر (على سبيل المثال، تطبيق الراديو) على جهاز بدون دعم المصدر هذا، فسيظل يعلن عن نفسه على أنه يتعامل مع غرض
ACTION_PLAY_BROADCASTRADIO
، لكن شجرة MediaBrowser الخاصة به لن تحتوي على علامات خاصة بالراديو. وبالتالي، يجب على العميل الراغب في التحقق من توفر مصدر معين على الجهاز:- اكتشف خدمة الراديو (اتصل بـ
resolveService
لـACTION_PLAY_BROADCASTRADIO
). - قم بإنشاء
MediaBrowser
ثم قم بالاتصال به. - حدد وجود
MediaItem
معEXTRA_BCRADIO_FOLDER_TYPE
الإضافي.
ملاحظة: في معظم الحالات، يجب على العميل فحص جميع أشجار MediaBrowser المتاحة لاكتشاف جميع المصادر المتاحة لجهاز معين.
أسماء الفرقة
يتم تمثيل قائمة النطاقات بمجموعة من أدلة المستوى الأعلى مع تعيين علامة نوع المجلد على
BCRADIO_FOLDER_TYPE_BAND
. عناوينMediaItem
الخاصة بهم هي سلاسل مترجمة تمثل أسماء النطاقات. في معظم الحالات، ستكون نفس الترجمة الإنجليزية، لكن لا يمكن للعميل الاعتماد على هذا الافتراض.لتوفير آلية مستقرة للبحث عن نطاقات معينة، تتم إضافة علامة إضافية لمجلدات النطاق،
EXTRA_BCRADIO_BAND_NAME_EN
. هذا اسم غير مترجم للنطاق ويمكن أن يأخذ واحدة فقط من هذه القيم المحددة مسبقًا:-
AM
-
FM
-
DAB
إذا لم يكن النطاق مدرجًا في هذه القائمة، فلا ينبغي تعيين علامة اسم النطاق. ومع ذلك، إذا كان النطاق مدرجًا في القائمة، فيجب أن يحتوي على مجموعة علامات. لا يقوم راديو HD بتعداد نطاقات منفصلة لأنه يستخدم نفس الوسيط الأساسي مثل AM/FM.
نوايا اللعب العامة
يجب أن يتعامل كل تطبيق مخصص لتشغيل مصدر معين (مثل الراديو أو القرص المضغوط) مع هدف تشغيل عام لبدء تشغيل بعض المحتوى ربما من حالة غير نشطة (على سبيل المثال، بعد التمهيد). يعود الأمر إلى التطبيق في كيفية تحديد المحتوى المطلوب تشغيله، ولكنه عادة ما يكون برنامج الراديو أو مسار القرص المضغوط الذي تم تشغيله مؤخرًا. هناك غرض منفصل محدد لكل مصدر صوتي:
-
android.car.intent.action.PLAY_BROADCASTRADIO
-
android.car.intent.action.PLAY_AUDIOCD
: CD-DA أو نص CD -
android.car.intent.action.PLAY_DATADISC
: قرص بيانات بصري مثل CD/DVD، ولكن ليس CD-DA (قد يكون قرصًا مضغوطًا ذو وضع مختلط) -
android.car.intent.action.PLAY_AUX
: بدون تحديد منفذ AUX -
android.car.intent.action.PLAY_BLUETOOTH
-
android.car.intent.action.PLAY_USB
: بدون تحديد جهاز USB -
android.car.intent.action.PLAY_LOCAL
: تخزين الوسائط المحلية (فلاش مدمج)
تم اختيار النوايا لاستخدامها في أمر اللعب العام، لأنها تحل مشكلتين في وقت واحد: أمر اللعب العام نفسه واكتشاف الخدمة. تتمثل الفائدة الإضافية لوجود مثل هذه النية في إمكانية تنفيذ مثل هذا الإجراء البسيط دون فتح جلسة MediaBrowser.
إن اكتشاف الخدمة هو في الواقع المشكلة الأكثر أهمية التي يتم حلها باستخدام هذه النوايا. يعد إجراء اكتشاف الخدمة سهلاً ولا لبس فيه بهذه الطريقة (راجع الاكتشاف والاتصال بالخدمة ).
لتسهيل بعض عمليات تنفيذ العميل، هناك طريقة بديلة لإصدار أمر Play (الذي يجب أيضًا تنفيذه بواسطة تطبيق الراديو): إصدار
playFromMediaId
باستخدام rootId للعقدة الجذرية (يستخدم كـ mediaId). على الرغم من أنه ليس من المفترض أن تكون العقدة الجذرية قابلة للتشغيل، إلا أن معرف الجذر الخاص بها عبارة عن سلسلة عشوائية يمكن جعلها قابلة للاستهلاك كمعرف وسائط. ومع ذلك، لا يطلب من العملاء فهم هذا الفارق الدقيق.محدد البرنامج
على الرغم من أن
mediaId
يكفي لتحديد قناة منMediaBrowserService
، إلا أنه يصبح مرتبطًا بالجلسة وغير متسق بين مقدمي الخدمة. في بعض الحالات، قد يحتاج العميل إلى مؤشر مطلق (مثل التردد المطلق) للحفاظ عليه بين الجلسات والأجهزة.في عصر البث الإذاعي الرقمي، لا يكفي التردد المجرد لضبط محطة معينة. ولذلك، استخدم
ProgramSelector
لتوليف قناة تمثيلية أو رقمية. يتكونProgramSelector
من جزأين:- المعرف الأساسي. معرف فريد وثابت لمحطة راديو معينة لا يتغير ولكنه قد لا يكون كافيًا لضبط تلك المحطة. على سبيل المثال، رمز RDS PI، والذي يمكن ترجمته إلى علامة الاتصال في الولايات المتحدة.
- المعرفات الثانوية معرفات إضافية مفيدة لضبط تلك المحطة (على سبيل المثال، التردد)، وربما تتضمن معرفات من تقنيات الراديو الأخرى. على سبيل المثال، قد تحتوي محطة DAB على بديل للبث التناظري.
لتمكين
ProgramSelector
من التوافق مع الحل المستند إلىMediaBrowser
- أوMediaSession
، قم بتعريف مخطط URI لإجراء تسلسل له. يتم تعريف المخطط على النحو التالي:broadcastradio://program/<primary ID type>/<primary ID>? <secondary ID type>=<secondary ID>&<secondary ID type>=<secondary ID>
في هذا المثال، يعد جزء المعرفات الثانوية (بعد علامة الاستفهام (
?
)) اختياريًا ويمكن إزالته لتوفير معرف ثابت لاستخدامه كـmediaId
. على سبيل المثال:-
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
يوفر جزء السلطة (AKA host) من
program
بعض المساحة لتمديد المخطط في المستقبل. يتم تحديد سلاسل نوع المعرف بدقة كاسمائها في تعريف HAL 2.x الخاص بـIdentifierType
ويكون تنسيق القيمة عبارة عن رقم عشري أو سداسي عشري (مع بادئة0x
).يتم تمثيل كافة المعرفات الخاصة بالبائع بواسطة البادئة
VENDOR_
. على سبيل المثال،VENDOR_0
لـVENDOR_START
وVENDOR_1
لـVENDOR_START
بالإضافة إلى 1. تكون معرفات URI هذه خاصة بأجهزة الراديو التي تم إنشاؤها عليها ولا يمكن نقلها بين الأجهزة التي تصنعها شركات تصنيع المعدات الأصلية المختلفة.يجب تعيين معرفات URI هذه لكل MediaItem ضمن مجلدات الراديو ذات المستوى الأعلى. بالإضافة إلى ذلك، يجب أن تدعم MediaSession كلا من
playFromMediaId
وplayFromUri
. ومع ذلك، فإن URI مخصص في المقام الأول لاستخراج البيانات التعريفية الراديوية (مثل تردد FM) والتخزين المستمر. ليس هناك ما يضمن أن URI سيكون متاحًا لجميع عناصر الوسائط (على سبيل المثال، عندما لا يكون نوع المعرف الأساسي مدعومًا من قبل إطار العمل). ومن ناحية أخرى، يعمل معرف الوسائط دائمًا. لا يُنصح بأن يستخدم العملاء URI لتحديد عناصر من جلسة MediaBrowser الحالية. بدلاً من ذلك، استخدمplayFromMediaId
. ومع ذلك، فهو ليس اختياريًا لتطبيق العرض ويتم حجز عناوين URI المفقودة للحالات المبررة جيدًا.استخدم التصميم الأولي نقطتين واحدتين بدلاً من التسلسل
://
بعد جزء المخطط. ومع ذلك، لا يتم دعم الأول بواسطةandroid.net.Uri
لمراجع URI الهرمية المطلقة.أنواع المصادر الأخرى
يمكن التعامل مع مصادر الصوت الأخرى بالمثل. على سبيل المثال، الإدخال المساعد ومشغل الأقراص المضغوطة الصوتية.
قد يخدم تطبيق واحد أنواعًا متعددة من المصادر. في مثل هذه الحالات، يوصى بإنشاء MediaBrowserService منفصلة لكل نوع من أنواع المصادر. حتى في الإعداد الذي يتضمن مصادر متعددة/MediaBrowserServices، يوصى بشدة أن يكون لديك جلسة MediaSession واحدة داخل تطبيق واحد.
قرص صوتي
يشبه القرص المضغوط الصوتي أن التطبيق الذي يخدم مثل هذه الأقراص سيكشف MediaBrowser بإدخال واحد قابل للتصفح (أو أكثر، إذا كان النظام يحتوي على مبدل أقراص مضغوطة)، والذي بدوره سيحتوي على جميع مسارات قرص مضغوط معين. إذا لم يكن لدى النظام معرفة بالمسارات الموجودة على كل قرص مضغوط (على سبيل المثال، عندما يتم إدخال كافة الأقراص في خرطوشة مرة واحدة ولا يقرأها جميعًا)، فسيكون MediaItem للقرص بأكمله
PLAYABLE
فقط، وليسBROWSABLE
بالإضافة إلىPLAYABLE
. إذا لم يكن هناك قرص في فتحة معينة، فلن يكون العنصرPLAYABLE
أوBROWSABLE
(ولكن يجب أن تكون كل فتحة موجودة دائمًا في الشجرة).سيتم وضع علامة على هذه الإدخالات بطريقة مشابهة لمجلدات البث الإذاعي؛ قد تحتوي على حقول إضافية محددة في MediaDescription API:
-
EXTRA_CD_TRACK
: لكلMediaItem
على قرص صوتي مضغوط، رقم مسار يعتمد على 1. -
EXTRA_CD_DISK
: رقم القرص المستند إلى 1.
بالنسبة للنظام الذي يدعم نص القرص المضغوط والقرص المتوافق، سيكون لعنصر MediaItem ذو المستوى الأعلى عنوان القرص. وبالمثل، فإن عناصر الوسائط الخاصة بالمسارات، سيكون لها عنوان للمسار.
إدخال مساعد
يعرض التطبيق الذي يقدم مدخلات مساعدة شجرة MediaBrowser ذات إدخال واحد (أو أكثر، في حالة وجود منافذ متعددة) يمثل منفذ AUX. تأخذ MediaSession المعنية معرف الوسائط الخاص بها وتتحول إلى هذا المصدر بعد الحصول على طلب
playFromMediaId
.سيكون لكل إدخال AUX MediaItem حقل إضافي
EXTRA_AUX_PORT_NAME
تم تعيينه على الاسم غير المترجم للمنفذ بدون عبارة "AUX". على سبيل المثال، سيتم تعيين "AUX 1" على "1"، و"AUX front" على "front" و"AUX" على سلسلة فارغة. في اللغات غير الإنجليزية، ستظل علامة الاسم هي نفس السلسلة الإنجليزية. من غير المحتمل كما هو الحال بالنسبة لـEXTRA_BCRADIO_BAND_NAME_EN
، أن تكون القيم محددة من قبل OEM وليست مقيدة بقائمة محددة مسبقًا.إذا تمكنت الجهاز من اكتشاف الأجهزة المتصلة بمنفذ AUX ، فيجب على الجهاز وضع علامة على MediaItem على أنها
PLAYABLE
، فقط إذا تم توصيل الإدخال. لا يزال ينبغي تعداد الأجهزة (ولكن لاPLAYABLE
) إذا لم يكن هناك شيء متصل بهذا المنفذ. إذا لم يكن للأجهزة أي إمكانية ، فيجب دائمًا تعيين MedioTem علىPLAYABLE
.حقول إضافية
تحديد الحقول التالية:
-
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"
يحتاج العميل إلى مراجعة Mediitems من المستوى الأعلى للعناصر التي تحتوي على مجموعة
EXTRA_CD_DISK
أوEXTRA_AUX_PORT_NAME
.أمثلة مفصلة
تتناول الأمثلة التالية بنية شجرة MediaBrowser لأنواع المصادر التي تشكل جزءًا من هذا التصميم.
Broadcast Radio MediaBrowSerService (معمل
ACTION_PLAY_BROADCASTRADIO
):- المحطات (متصفح)
EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_PROGRAMS
- BBC One (قابلة للعب) URI:
broadcastradio://program/RDS_PI/1234?AMFM_FREQUENCY=90500
- ABC 88.1 (قابلة للعب) URI:
broadcastradio://program/RDS_PI/5678?AMFM_FREQUENCY=88100
- ABC 88.1 HD1 (قابلة للعب) URI:
broadcastradio://program/HD_STATION_ID_EXT/158241DEADBEEF?AMFM_FREQUENCY=88100&RDS_PI=5678
- ABC 88.1 HD2 (قابلة للعب) URI:
broadcastradio://program/HD_STATION_ID_EXT/158242DEADBEFE
- 90.5 FM (قابلة للعب) - FM بدون RDSURI:
broadcastradio://program/AMFM_FREQUENCY/90500
- 620 صباحًا (قابلة للعب) URI:
broadcastradio://program/AMFM_FREQUENCY/620
- BBC One (قابلة للعب) URI:
broadcastradio://program/DAB_SID_EXT/1E24102?RDS_PI=1234
- BBC One (قابلة للعب) URI:
- المفضلة (قابلة للتصفح ، قابلة للعب)
EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_FAVORITES
- BBC One (قابلة للعب) URI:
broadcastradio://program/RDS_PI/1234?AMFM_FREQUENCY=101300
- BBC Two (غير قابل للعب) URI:
broadcastradio://program/RDS_PI/1300?AMFM_FREQUENCY=102100
- BBC One (قابلة للعب) URI:
- AM (قابل للتصفح ، قابل للعب):
EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_BANDEXTRA_BCRADIO_BAND_NAME_EN="AM"
- 530 صباحًا (قابلة للعب) URI:
broadcastradio://program/AMFM_FREQUENCY/530
- 540 صباحًا (قابلة للعب) URI:
broadcastradio://program/AMFM_FREQUENCY/540
- 550 صباحًا (قابلة للعب) URI:
broadcastradio://program/AMFM_FREQUENCY/550
- 530 صباحًا (قابلة للعب) URI:
- FM (قابل للتصفح ، قابل للعب):
EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_BANDEXTRA_BCRADIO_BAND_NAME_EN="FM"
- 87.7 FM (قابلة للعب) URI:
broadcastradio://program/AMFM_FREQUENCY/87700
- 87.9 FM (قابلة للعب) URI:
broadcastradio://program/AMFM_FREQUENCY/87900
- 88.1 FM (قابلة للعب) URI:
broadcastradio://program/AMFM_FREQUENCY/88100
- 87.7 FM (قابلة للعب) URI:
- dab (قابلة للعب):
EXTRA_BCRADIO_FOLDER_TYPE=BCRADIO_FOLDER_TYPE_BANDEXTRA_BCRADIO_BAND_NAME_EN="DAB"
Audio CD MediaBrowSerservice (تعامل
ACTION_PLAY_AUDIOCD
):- القرص 1 (قابل للعب)
EXTRA_CD_DISK=1
- القرص 2 (قابل للتصفح ، قابل للعب)
EXTRA_CD_DISK=2
- المسار 1 (قابل للتشغيل)
EXTRA_CD_TRACK=1
- المسار 2 (قابل للتشغيل)
EXTRA_CD_TRACK=2
- المسار 1 (قابل للتشغيل)
- قرص الموسيقى الخاص بي (قابل للتصفح ، قابل للتشغيل)
EXTRA_CD_DISK=3
- كل ذلك بنفسي (قابل للعب)
EXTRA_CD_TRACK=1
- reise ، reise (playable)
EXTRA_CD_TRACK=2
- كل ذلك بنفسي (قابل للعب)
- الفتحة الفارغة 4 (غير قابلة للعب)
EXTRA_CD_DISK=4
Aux MediaBrowserservice (تعامل
ACTION_PLAY_AUX
):- Aux Front (قابلة للعب)
EXTRA_AUX_PORT_NAME="front"
- AUX الخلفية (قابلة للعب)
EXTRA_AUX_PORT_NAME="rear"
-