يجب نقل البيانات من التطبيقات التي تستخدم حاليًا مكتبة 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 Studio، واطّلِع على 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()
: تُستخدَم دالة callbackonAddMediaItems(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 API لتكون كبيرة جدًا، وذلك للسماح للتطبيقات بتخصيص كل جوانب التشغيل تقريبًا. قد تُجري الإصدارات اللاحقة من ExoPlayer أحيانًا عمليات إعادة تسمية للرموز أو تغييرات أخرى أساسية (مثل الطرق المطلوبة الجديدة في الواجهات). في معظم الحالات، تم تخفيف هذه الأعطال من خلال تقديم الرمز الجديد إلى جانب إيقاف الرمز القديم نهائيًا في بضعة إصدارات، للسماح للمطوّرين بوقت لنقل استخداماتهم، ولكن لم يكن ذلك ممكنًا في بعض الأحيان.
أدّت هذه التغييرات الأساسية إلى حدوث مشكلتَين لمستخدمي مكتبتَي ExoPlayer v1 وv2:
- قد تؤدي الترقية من الإصدار إلى إصدار ExoPlayer إلى إيقاف تجميع الرمز.
- كان على التطبيق الذي يعتمد على ExoPlayer مباشرةً وعبر مكتبة intermedial التأكّد من أنّ كلا الملحقَين هما من الإصدار نفسه، وإلا قد تؤدي عدم التوافق بين الملفات الثنائية إلى حدوث أعطال أثناء التشغيل.
تحسينات في Media3
تضمن Media3 توافق الثنائيات لمجموعة فرعية من مساحة عرض واجهة برمجة التطبيقات. يتم وضع علامة
@UnstableApi
على
الأجزاء التي لا تضمن التوافق الثنائي. لتوضيح هذا الفرق، تؤدي استخدامات رموزال واجهة برمجة التطبيقات غير المستقرة
إلى ظهور خطأ في أداة lint ما لم يتم وضع تعليق توضيحي عليها باستخدام @OptIn
.
بعد نقل البيانات من الإصدار 2 من ExoPlayer إلى Media3، قد تظهر لك الكثير من أخطاء فحص أخطاء API غير المستقرة. قد يؤدي ذلك إلى ظهور Media3 على أنّه "أقل ثباتًا" من الإصدار 2 من ExoPlayer. هذا ليس صحيحًا. تتمتع الأجزاء "غير المستقرة" من Media3 API بالثبات نفسه الذي تتمتع به واجهة برمجة التطبيقات الكاملة لواجهة برمجة التطبيقات ExoPlayer v2، ولا تتوفّر ضمانات واجهة برمجة التطبيقات Media3 API الثابتة في ExoPlayer v2 على الإطلاق. والفرق هو أنّ خطأ التدقيق الآن يُنبّهك إلى مستويات الثبات المختلفة.
التعامل مع أخطاء فحص الأخطاء في واجهة برمجة التطبيقات غير المستقرة
اطّلِع على قسم تحديد المشاكل وحلّها في ما يتعلّق بأخطاء lint هذه للحصول على تفاصيل حول كيفية
إضافة تعليقات توضيحية إلى استخدامات Java وKotlin لواجهات برمجة التطبيقات غير المستقرة باستخدام @OptIn
.
واجهات برمجة التطبيقات المتوقّفة نهائيًا
قد تلاحظ أنّ طلبات البيانات من واجهات برمجة التطبيقات المتوقّفة نهائيًا يتم وضع خط عليها في Android Studio. ننصحك باستبدال هذه المكالمات بالبديل المناسب. مرِّر مؤشر الماوس فوق الرمز للاطّلاع على JavaDoc الذي يحدّد واجهة برمجة التطبيقات التي يجب استخدامها بدلاً من ذلك.
عيّنات التعليمات البرمجية والتطبيقات التجريبية
- تطبيق تجريبي لجلسة AndroidX Media3 (للأجهزة الجوّالة ونظام التشغيل WearOS)
- الإجراءات المخصّصة
- إشعار واجهة المستخدم للنظام، MediaButton/BT
- عناصر التحكّم في التشغيل من خلال "مساعد Google"
- UAMP: مشغّل وسائط Android (branch media3) (الأجهزة الجوّالة، AutomotiveOS)
- إشعار واجهة المستخدم للنظام، زر الوسائط/البلوتوث، استئناف التشغيل
- عناصر التحكّم في التشغيل في "مساعد Google"/WearOS
- AutomotiveOS: الأوامر المخصّصة وتسجيل الدخول