يجب نقل البيانات من التطبيقات التي تستخدم حاليًا مكتبة com.google.android.exoplayer2
وandroidx.media
المستقلة إلى androidx.media3
. استخدِم
النص البرمجي لنقل البيانات لنقل ملفات إنشاء Gradle وملفات رمز Java و
Kotlin المصدر وملفات تنسيق XML من ExoPlayer
2.19.1
إلى AndroidX Media3 1.1.1
.
نظرة عامة
قبل إجراء عملية النقل، راجِع الأقسام التالية للاطّلاع على مزيد من المعلومات حول مزايا واجهات برمجة التطبيقات وواجهات برمجة التطبيقات الجديدة المطلوب نقلها والمتطلبات الأساسية التي يجب أن يستوفيها مشروع تطبيقك.
أسباب نقل البيانات إلى Jetpack Media3
- وهو المنزل الجديد لواجهة ExoPlayer، في حين تم
إيقاف
com.google.android.exoplayer2
نهائيًا. - يمكنك الوصول إلى Player API في جميع المكوّنات/العمليات باستخدام
MediaBrowser
/MediaController
. - استخدِم الإمكانات الموسّعة لواجهات برمجة التطبيقات
MediaSession
وMediaController
. - الإعلان عن إمكانات التشغيل باستخدام التحكّم الدقيق في الوصول
- بسِّط تطبيقك عن طريق إزالة
MediaSessionConnector
وPlayerNotificationManager
. - متوافقة مع الإصدارات القديمة من واجهات برمجة تطبيقات العميل المتوافقة مع الوسائط
(
MediaBrowserCompat
/MediaControllerCompat
/MediaMetadataCompat
)
واجهات برمجة تطبيقات الوسائط لنقل البيانات إلى AndroidX Media3
- ExoPlayer والإضافات
يشمل ذلك جميع وحدات مشروع ExoPlayer القديم باستثناء وحدة mediasession التي تم إيقافها نهائيًا. يمكن نقل التطبيقات أو الوحدات المستندة إلى الحزم فيcom.google.android.exoplayer2
باستخدام النص البرمجي لنقل البيانات. - MediaSessionConnector (حسب
حِزم
androidx.media.*
منandroidx.media:media:1.4.3+
)
أزِلMediaSessionConnector
واستخدِمandroidx.media3.session.MediaSession
بدلاً منه. - MediaBrowserServiceCompat (اعتمادًا على حزم
androidx.media.*
الخاصة بـandroidx.media:media:1.4.3+
)
يمكنك نقل الفئات الفرعية منandroidx.media.MediaBrowserServiceCompat
إلىandroidx.media3.session.MediaLibraryService
واستخدام الرموز البرمجية من خلالMediaBrowserCompat.MediaItem
إلىandroidx.media3.common.MediaItem
. - MediaBrowserCompat (حسب حزم
android.support.v4.media.*
منandroidx.media:media:1.4.3+
)
نقل رمز العميل باستخدامMediaBrowserCompat
أوMediaControllerCompat
لاستخدامandroidx.media3.session.MediaBrowser
معandroidx.media3.common.MediaItem
المتطلّبات الأساسية
التأكّد من أنّ مشروعك خاضع لإدارة مصدر
تأكَّد من أنّه يمكنك بسهولة التراجع عن التغييرات التي تُطبّقها أدوات نقل البيانات البرمجية. إذا لم يكن مشروعك خاضعًا لإدارة مصدر المحتوى بعد، هذا هو الوقت المناسب لبدء استخدامه. إذا كنت لا تريد إجراء ذلك لأي سبب، أنشئ نسخة احتياطية من مشروعك قبل بدء عملية نقل البيانات.
تحديث تطبيقك
ننصحك بتحديث مشروعك لاستخدام أحدث إصدار من مكتبة ExoPlayer وإزالة أي طلبات للوصول إلى الطرق المتوقّفة نهائيًا. إذا كنت تنوي استخدام النص البرمجي لنقل البيانات، عليك مطابقة الإصدار الذي يتم التحديث إليه مع الإصدار الذي يعالجه النص البرمجي.
عليك زيادة compileSdkVersion لتطبيقك إلى 32 على الأقل.
ترقية Gradle والمكوّن الإضافي Gradle في "استوديو Android" إلى إصدار حديث متوافق مع الملحقات المعدّلة المذكورة أعلاه على سبيل المثال:
- إصدار المكوّن الإضافي لنظام Gradle المتوافق مع Android: 7.1.0
- إصدار Gradle: 7.4
استبدِل كل عبارات الاستيراد التي تستخدم العلامة النجمية (*) واستخدِم عبارات الاستيراد المؤهَّلة بالكامل: احذف عبارات استخدام العلامة النجمية لاستيراد عبارات استخدام العلامة النجمية بالكامل (F2 - Alt/Enter، F2 - Alt/Enter، ...).
نقل البيانات من
com.google.android.exoplayer2.PlayerView
إلىcom.google.android.exoplayer2.StyledPlayerView
هذا الإجراء ضروري لأنه لا يتوفّر بديل لسمةcom.google.android.exoplayer2.PlayerView
في حزمة AndroidX Media3.
نقل بيانات ExoPlayer مع إتاحة النصوص البرمجية
يسهّل النص البرمجي الانتقال من com.google.android.exoplayer2
إلى بنية الحزمة والوحدة الجديدة ضمن androidx.media3
. يطبق النص البرمجي بعض عمليات التحقق من الصحة على مشروعك ويطبع التحذيرات في حالة فشل التحقق من الصحة.
وبخلاف ذلك، يطبّق عمليات الربط للفئات والحِزم التي تمت إعادة تسميتها في
موارد مشروع Android gradle المكتوب بلغة Java أو Kotlin.
usage: ./media3-migration.sh [-p|-c|-d|-v]|[-m|-l [-x <path>] [-f] PROJECT_ROOT]
PROJECT_ROOT: path to your project root (location of 'gradlew')
-p: list package mappings and then exit
-c: list class mappings (precedence over package mappings) and then exit
-d: list dependency mappings and then exit
-l: list files that will be considered for rewrite and then exit
-x: exclude the path from the list of file to be changed: 'app/src/test'
-m: migrate packages, classes and dependencies to AndroidX Media3
-f: force the action even when validation fails
-v: print the exoplayer2/media3 version strings of this script
-h, --help: show this help text
استخدام نص نقل البيانات
نزِّل النص البرمجي لنقل البيانات من علامة مشروع ExoPlayer على GitHub المتوافقة مع الإصدار الذي تم تحديث تطبيقك إليه:
curl -o media3-migration.sh \ "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
اجعل النص البرمجي قابلاً للتنفيذ:
chmod 744 media3-migration.sh
يمكنك تشغيل النص البرمجي باستخدام
--help
للتعرّف على الخيارات.يمكنك تشغيل النص البرمجي باستخدام
-l
لعرض مجموعة الملفات التي تم اختيارها لنقلها (استخدِم-f
لفرض عرض القائمة بدون تحذيرات):./media3-migration.sh -l -f /path/to/gradle/project/root
شغِّل النص البرمجي باستخدام
-m
لربط الحِزم والفصول والوحدات بـ Media3. سيؤدي تشغيل النص البرمجي باستخدام الخيار-m
إلى تطبيق التغييرات على الملفات المحدّدة.- التوقف عند حدوث خطأ في التحقّق من الصحة بدون إجراء تغييرات
./media3-migration.sh -m /path/to/gradle/project/root
- التنفيذ القسري
إذا كشف النص البرمجي عن مخالفة للمتطلبات الأساسية، يمكن فرض عملية النقل باستخدام علامة
-f
:./media3-migration.sh -m -f /path/to/gradle/project/root
# list files selected for migration when excluding paths
./media3-migration.sh -l -x "app/src/test/" -x "service/" /path/to/project/root
# migrate the selected files
./media3-migration.sh -m -x "app/src/test/" -x "service/" /path/to/project/root
أكمِل الخطوات اليدوية التالية بعد تشغيل النص البرمجي باستخدام الخيار -m
:
- التحقّق من الطريقة التي غيّر بها النص البرمجي رمزك: استخدِم أداة مختلفة وأصلح
المشاكل المحتملة (يمكنك الإبلاغ عن خطأ إذا كنت تعتقد أنّ النص البرمجي يتضمّن
مشكلة عامة تم طرحها بدون ضبط الخيار
-f
). - إنشاء المشروع: يمكنك استخدام
./gradlew clean build
أو في "استوديو Android"، اختَر ملف > مزامنة المشروع مع ملفات Gradle، ثم إنشاء > تنظيف المشروع، ثم إنشاء > إعادة إنشاء المشروع (يمكنك تتبُّع عملية الإنشاء في علامة التبويب "إنشاء - نتيجة الإنشاء" في "استوديو Android").
خطوات المتابعة المقترَحة:
- حلّ مشكلة تفعيل الأخطاء المتعلّقة باستخدام واجهات برمجة التطبيقات غير المستقرة
- استبدال طلبات بيانات واجهة برمجة التطبيقات التي تم إيقافها نهائيًا: استخدِم واجهة برمجة التطبيقات البديلة المقترَحة. ضع مؤشر الماوس فوق التحذير في "استوديو Android" وراجع JavaDoc الخاص بالرمز الذي تم إيقافه لمعرفة ما يجب استخدامه بدلاً من طلب معيّن.
- ترتيب عبارات الاستيراد: افتح المشروع في "استوديو Android"، ثم انقر بزر الماوس الأيمن على عقدة مجلد الحزمة في عارض المشروع واختَر تحسين عمليات الاستيراد في الحزم التي تحتوي على الملفات المصدر التي تمّ تغييرها.
استبدال MediaSessionConnector
بـ androidx.media3.session.MediaSession
في الإصدار القديم من MediaSessionCompat
، كان MediaSessionConnector
مسؤولاً عن مزامنة حالة المشغّل مع حالة الجلسة
وتلقّي الأوامر من أدوات التحكّم التي كانت بحاجة إلى تفويض إلى مثيل methods المناسب لـ
المشغّل. باستخدام AndroidX Media3، يتم ذلك من خلال MediaSession
مباشرةً
بدون الحاجة إلى محوِّل.
إزالة جميع الإشارات إلى MediaSessionConnector واستخدامها: إذا كنت قد استخدمت النص البرمجي المبرمَج لنقل فئات حِزم ExoPlayer، من المرجّح أنّه قد ترك النص البرمجي رمزك في حالة لا يمكن تجميعها بشأن
MediaSessionConnector
التي لا يمكن حلّها. سيُظهر لك Android Studio الرمز البرمجي الذي يتضمّن خطأ عند محاولة إنشاء التطبيق أو تشغيله.في ملف
build.gradle
الذي تحتفظ فيه بالملحقات، أضِف ملحق تنفيذ إلى وحدة جلسة AndroidX Media3 وأزِل الملحق القديم:implementation "androidx.media3:media3-session:1.4.1"
استبدِل
MediaSessionCompat
بـandroidx.media3.session.MediaSession
.في موقع الرمز الذي أنشأت فيه
MediaSessionCompat
القديم، استخدِمandroidx.media3.session.MediaSession.Builder
من أجل إنشاءMediaSession
. اضبط المشغّل لإنشاء أداة إنشاء الجلسات.val player = ExoPlayer.Builder(context).build() mediaSession = MediaSession.Builder(context, player) .setSessionCallback(MySessionCallback()) .build()
يمكنك تنفيذ
MySessionCallback
حسب متطلبات تطبيقك. وهذه الخطوة اختيارية. إذا أردت السماح لعناصر التحكّم بإضافة عناصر وسائط إلى المشغّل، نفِّذMediaSession.Callback.onAddMediaItems()
. ويقدّم هذا الإصدار طرقًا مختلفة حالية و قديمة لواجهة برمجة التطبيقات تضيف عناصر وسائط إلى المشغّل لتشغيلها بطريقة متوافقة مع الإصدارات القديمة. ويشمل ذلك methodsMediaController.set/addMediaItems()
لوحدة التحكّم في Media3، بالإضافة إلى methodsTransportControls.prepareFrom*/playFrom*
لواجهة برمجة التطبيقات القديمة. يمكن العثور على نموذج لتنفيذonAddMediaItems
فيPlaybackService
في تطبيق العرض التوضيحي للجلسة.يمكنك إلغاء جلسة الوسائط في موقع الرمز البرمجي الذي ألغيت فيه جلستك قبل نقل البيانات:
mediaSession?.run { player.release() release() mediaSession = null }
وظائف MediaSessionConnector
في Media3
يعرض الجدول التالي واجهات برمجة تطبيقات Media3 التي تتعامل مع الوظائف التي تم تنفيذها سابقًا في MediaSessionConnector
.
MediaSessionConnector | AndroidX Media3 |
---|---|
CustomActionProvider |
MediaSession.Callback.onCustomCommand()/
MediaSession.setCustomLayout() |
PlaybackPreparer |
MediaSession.Callback.onAddMediaItems()
(يتمّ استدعاء prepare() داخليًا)
|
QueueNavigator |
ForwardingPlayer |
QueueEditor |
MediaSession.Callback.onAddMediaItems() |
RatingCallback |
MediaSession.Callback.onSetRating() |
PlayerNotificationManager |
DefaultMediaNotificationProvider/
MediaNotification.Provider |
نقل MediaBrowserService
إلى MediaLibraryService
يقدّم AndroidX Media3 MediaLibraryService
الذي يحلّ محل
MediaBrowserServiceCompat
. يوفّر ملف JavaDoc الخاص بـ MediaLibraryService
و
طبقته الفائقة MediaSessionService
مقدمة جيدة عن واجهة برمجة التطبيقات و
نموذج البرمجة غير المتزامنة للخدمة.
تتوافق السمة MediaLibraryService
مع الإصدارات القديمة مع "MediaBrowserService
". يستمر تطبيق العميل الذي يستخدم MediaBrowserCompat
أو
MediaControllerCompat
في العمل بدون تغييرات في الرمز عند الربط
بتطبيق MediaLibraryService
. بالنسبة إلى العميل، يكون من الواضح ما إذا كان تطبيقك
يستخدِم MediaLibraryService
أو MediaBrowserServiceCompat
قديمًا.
لكي تعمل التوافقية مع الإصدارات القديمة، عليك تسجيل كل من منصتي IDE مع خدمتك في
AndroidManifest.xml
. بهذه الطريقة، يعثر العميل على خدمتك من خلال واجهة الخدمة المطلوبة:<service android:name=".MusicService" android:exported="true"> <intent-filter> <action android:name="androidx.media3.session.MediaLibraryService"/> <action android:name="android.media.browse.MediaBrowserService" /> </intent-filter> </service>
في ملف
build.gradle
الذي تحتفظ فيه بالملحقات، أضِف تبعية التنفيذ إلى وحدة جلسة AndroidX Media3 وأزِل التبعية القديمة:implementation "androidx.media3:media3-session:1.4.1"
غيِّر خدمتك لترث من
MediaLibraryService
بدلاً منMediaBrowserService
كما ذكرنا سابقًا، يتوافقMediaLibraryService
مع الإصدار القديمMediaBrowserService
. وبناءً على ذلك، تظل واجهة برمجة التطبيقات الأوسع نطاقًا التي تقدّمها الخدمة للعملاء كما هي. لذا من المحتمل أن يستطيع أي تطبيق الاحتفاظ بمعظم منطق تنفيذMediaBrowserService
وتعديله بما يتناسب معMediaLibraryService
الجديد.في ما يلي الاختلافات الرئيسية مقارنةً بالإصدار القديم
MediaBrowserServiceCompat
:تنفيذ طرق دورة حياة الخدمة: الطرق التي يجب تجاوزها في الخدمة نفسها هي
onCreate/onDestroy
، حيث يخصّص/يُطلق التطبيق جلسة المكتبة والمشغّل وغيرها من موارد التطبيق. بالإضافة إلى طرق دورة حياة الخدمة العادية، يجب أن يتجاوز التطبيقonGetSession(MediaSession.ControllerInfo)
لعرضMediaLibrarySession
الذي تم إنشاؤه فيonCreate
.تنفيذ MediaLibraryService.MediaLibrarySessionCallback: يتطلّب إنشاء جلسة استخدام
MediaLibraryService.MediaLibrarySessionCallback
الذي ينفِّذ methodsواجهة برمجة تطبيقات النطاق الفعلية. لذا، بدلاً من إلغاء طرق واجهة برمجة التطبيقات للخدمة القديمة، عليك إلغاء طرقMediaLibrarySession.Callback
بدلاً من ذلك.بعد ذلك، يتم استخدام دالة الاستدعاء لإنشاء
MediaLibrarySession
:mediaLibrarySession = MediaLibrarySession.Builder(this, player, MySessionCallback()) .build()
ابحث عن واجهة برمجة التطبيقات الكاملة لواجهة MediaLibrarySessionCallback في مستندات واجهة برمجة التطبيقات.
تنفيذ
MediaSession.Callback.onAddMediaItems()
: دالة الاستدعاءonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)
تعرض مجموعة من الطرق الحالية والقديمة لواجهة برمجة التطبيقات التي تضيف ملفات وسائط إلى المشغّل بطريقة متوافقة مع الأنظمة القديمة. ويشمل ذلك methodsMediaController.set/addMediaItems()
لوحدة التحكّم في Media3، بالإضافة إلى methodsTransportControls.prepareFrom*/playFrom*
لواجهة برمجة التطبيقات القديمة. يمكن العثور على نموذج لتنفيذ طلب إعادة الاتصال فيPlaybackService
من تطبيق الإصدار التجريبي للجلسة.يستخدم حِزم AndroidX Media3
androidx.media3.common.MediaItem
بدلاً من MediaBrowserCompat.MediaItem وMediaMetadataCompat. يجب تغيير أجزاء من الرمز البرمجي المرتبطة بالفئات القديمة وفقًا لذلك أو ربطها بـ Media3MediaItem
بدلاً من ذلك.تم تغيير نموذج البرمجة غير المتزامنة إلى
Futures
العام على عكس أسلوبResult
القابل للفصل في "MediaBrowserServiceCompat
". يمكن أن يعرض تنفيذ الخدمةListenableFuture
غير المتزامن بدلاً من فصل النتيجة أوعرض Future فوري لعرض قيمة مباشرةً.
إزالة PlayerNotificationManager
يتوافق "MediaLibraryService
" مع إشعارات الوسائط تلقائيًا ويمكن إزالة
"PlayerNotificationManager
" عند استخدام MediaLibraryService
أو
MediaSessionService
.
يمكن للتطبيق تخصيص الإشعار من خلال ضبط
MediaNotification.Provider
مخصّص في onCreate()
ليحلّ محل
DefaultMediaNotificationProvider
. بعد ذلك، يتولى MediaLibraryService
بدء الخدمة في المقدّمة على النحو المطلوب.
من خلال إلغاء MediaLibraryService.updateNotification()
، يمكن للتطبيق أن يحصل على
الملكية الكاملة لنشر إشعار وبدء الخدمة أو إيقافها في
المقدّمة حسب الحاجة.
نقل رمز العميل باستخدام MediaBrowser
في AndroidX Media3، MediaBrowser
لتنفيذ الواجهات MediaController/Player
ويمكن استخدامه للتحكم في تشغيل الوسائط إلى جانب تصفُّح مكتبة الوسائط. إذا كان عليك إنشاء MediaBrowserCompat
و
MediaControllerCompat
في الإصدار القديم، يمكنك إجراء ذلك باستخدام
MediaBrowser
فقط في Media3.
يمكن إنشاء MediaBrowser
والانتظار إلى أن يتم إنشاء اتصال
بالخدمة:
scope.launch {
val sessionToken =
SessionToken(context, ComponentName(context, MusicService::class.java)
browser =
MediaBrowser.Builder(context, sessionToken))
.setListener(BrowserListener())
.buildAsync()
.await()
// Get the library root to start browsing the library.
root = browser.getLibraryRoot(/* params= */ null).await();
// Add a MediaController.Listener to listen to player state events.
browser.addListener(playerListener)
playerView.setPlayer(browser)
}
اطّلِع على مقالة
التحكّم في التشغيل في جلسة الوسائط
لمعرفة كيفية إنشاء MediaController
للتحكّم في التشغيل في
الخلفية.
خطوات إضافية وإزالة البرامج الضارة
أخطاء واجهة برمجة التطبيقات غير الثابتة
بعد نقل البيانات إلى Media3، قد تظهر لك أخطاء فحص الأخطاء المتعلقة باستخدامات واجهة برمجة التطبيقات غير المستقرة.
إنّ واجهات برمجة التطبيقات هذه آمنة للاستخدام، وتعدّ أخطاء "أداة فحص الأخطاء البرمجية" نتيجة ثانوية لضمانات التوافق الجديدة
للملفات الثنائية. إذا كنت لا تطلب توافقًا ثنائيًا صارمًا،
يمكن منع هذه الأخطاء بأمان باستخدام تعليق توضيحي @OptIn
.
خلفية
لم يقدّم الإصدار 1 أو الإصدار 2 من ExoPlayer ضمانات صارمة بشأن التوافق الثنائي للمكتبة بين الإصدارات اللاحقة. تكون مساحة واجهة برمجة التطبيقات ExoPlayer كبيرة جدًا من حيث التصميم، وتتيح للتطبيقات تخصيص كل جانب من جوانب التشغيل تقريبًا. قد تُجري الإصدارات اللاحقة من ExoPlayer أحيانًا عمليات إعادة تسمية لرموزه أو تغييرات جذرية أخرى (مثل طُرق مطلوبة جديدة على الواجهات). في معظم الحالات، تم تخفيف هذه الأعطال من خلال تقديم الرمز الجديد إلى جانب إيقاف الرمز القديم نهائيًا في بضعة إصدارات، للسماح للمطوّرين بوقت لنقل استخداماتهم، ولكن لم يكن ذلك ممكنًا في بعض الأحيان.
أدّت هذه التغييرات الأساسية إلى حدوث مشكلتَين لمستخدمي مكتبتَي ExoPlayer v1 وv2:
- وقد تؤدي الترقية من إصدار ExoPlayer إلى إيقاف تجميع الرمز.
- كان على التطبيق الذي يعتمد على ExoPlayer مباشرةً وعبر مكتبة intermedial التأكّد من أنّ كلا الملحقَين هما من الإصدار نفسه، وإلا قد تؤدي عدم التوافق بين الملفات الثنائية إلى حدوث أعطال أثناء التشغيل.
تحسينات في Media3
تضمن Media3 توافق الثنائيات لمجموعة فرعية من مساحة عرض واجهة برمجة التطبيقات. وقد تم وضع علامة @UnstableApi
على الأجزاء التي لا تضمن التوافق الثنائي معها. لتوضيح هذا الفرق، تؤدي استخدامات رموزال واجهة برمجة التطبيقات غير المستقرة
إلى ظهور خطأ في أداة lint ما لم يتم وضع تعليق توضيحي عليها باستخدام @OptIn
.
بعد الترحيل من ExoPlayer v2 إلى Media3، قد تظهر لك الكثير من أخطاء أداة Lint غير المستقرة لواجهة برمجة التطبيقات. وقد يجعل ذلك يبدو أن Media3 "أقل ثباتًا" من الإصدار 2 من ExoPlayer. هذا ليس صحيحًا. تتمتع الأجزاء "غير المستقرة" من Media3 API بالثبات نفسه الذي تتمتع به واجهة برمجة التطبيقات الكاملة لواجهة برمجة التطبيقات ExoPlayer v2، ولا تتوفّر ضمانات واجهة برمجة التطبيقات Media3 API الثابتة في ExoPlayer v2 على الإطلاق. والفرق هو أنّ خطأ التدقيق الآن يُنبّهك إلى مستويات الثبات المختلفة.
معالجة أخطاء أداة Lint غير الثابتة لواجهة برمجة التطبيقات
اطّلِع على قسم تحديد المشاكل وحلّها في ما يتعلّق بأخطاء Lint هذه للحصول على تفاصيل حول كيفية
إضافة تعليقات توضيحية إلى استخدامات Java وKotlin لواجهات برمجة التطبيقات غير المستقرة باستخدام @OptIn
.
واجهات برمجة التطبيقات المتوقّفة نهائيًا
قد تلاحظ أنّ طلبات البيانات من واجهات برمجة التطبيقات المتوقّفة نهائيًا مشطوبة في Android Studio. نقترح استبدال هذه المكالمات بالبديل المناسب. مرِّر مؤشر الماوس فوق الرمز للاطّلاع على JavaDoc الذي يحدّد واجهة برمجة التطبيقات التي يجب استخدامها بدلاً من ذلك.
عيّنات التعليمات البرمجية والتطبيقات التجريبية
- التطبيق التجريبي لجلسة AndroidX Media3 (الأجهزة الجوّالة وأجهزة WearOS)
- الإجراءات المخصّصة
- إشعار واجهة المستخدم للنظام، MediaButton/BT
- عناصر التحكّم في التشغيل من خلال "مساعد Google"
- UAMP: مشغّل وسائط Android (branch media3) (الأجهزة الجوّالة، AutomotiveOS)
- إشعار واجهة المستخدم للنظام، زر الوسائط/البلوتوث، استئناف التشغيل
- عناصر التحكّم في التشغيل في "مساعد Google"/WearOS
- AutomotiveOS: الطلب المخصَّص وتسجيل الدخول