التطبيقات التي تستخدم حاليًا "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
API. - الإعلان عن إمكانات التشغيل باستخدام عنصر تحكّم دقيق في الوصول
- تبسيط تطبيقك من خلال إزالة
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
استبدال جميع عبارات استيراد أحرف البدل التي تستخدم علامة النجمة (*) واستخدام عبارات الاستيراد المؤهلة بالكامل: حذف حرف البدل بيانات الاستيراد واستخدام "استوديو Android" لاستيراد البيانات العبارات (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
المسئولة عن مزامنة حالة المشغل مع حالة الجلسة
وتلقّي الأوامر من وحدات التحكم التي تحتاج إلى تفويض
واللاعبين. يتم تنفيذ ذلك من خلال AndroidX Media3 بواسطة MediaSession
مباشرةً
بدون الحاجة إلى موصل.
إزالة جميع المراجع واستخدام MediaSessionConnector: إذا كنت قد استخدمت النص البرمجي الآلي لنقل فئات وحزم ExoPlayer، ثم من المحتمل أن يكون النص البرمجي قد ترك الرمز في حالة غير قابلة للتجميع
MediaSessionConnector
التي لا يمكن حلها. سيتيح لك "استوديو Android" سيظهر لك الرمز المعطّل عند محاولة إنشاء التطبيق أو تشغيله.في ملف
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()
يخدم العديد من المواقع طرق واجهة برمجة التطبيقات القديمة التي تضيف ملفات الوسائط إلى المشغّل لتشغيلها في متوافقة مع الأنظمة القديمة. ويتضمن ذلكMediaController.set/addMediaItems()
طريقة لوحدة تحكم Media3، باسم بالإضافة إلىTransportControls.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
قديم.
لكي يعمل التوافق مع الأنظمة القديمة، يجب تسجيل كلتا الخدمتين. بخدمتك في
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
التي تنفّذ طرق واجهة برمجة تطبيقات النطاق الفعلية. لذا بدلاً من إلغاء طرق واجهة برمجة التطبيقات الخدمة القديمة، فستلغي طرقMediaLibrarySession.Callback
بدلاً من ذلك.بعد ذلك، يتم استخدام هذه الدالة لإنشاء
MediaLibrarySession
:mediaLibrarySession = MediaLibrarySession.Builder(this, player, MySessionCallback()) .build()
ابحث عن واجهة برمجة التطبيقات الكاملة لـ MediaLibrarySessionCallback في واجهة برمجة التطبيقات. التوثيق.
تنفيذ
MediaSession.Callback.onAddMediaItems()
: معاودة الاتصال عدد مرات العرض:onAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)
طرق مختلفة حالية وقديمة لواجهة برمجة التطبيقات تضيف ملفات الوسائط إلى المشغّل للتشغيل بطريقة متوافقة مع الأنظمة القديمة. ويتضمن ذلكMediaController.set/addMediaItems()
طريقة لوحدة التحكم Media3، فضلاً عنTransportControls.prepareFrom*/playFrom*
واجهة برمجة التطبيقات القديمة. يمكن لتنفيذ نموذجي لمعاودة الاتصال يمكن العثور عليها فيPlaybackService
من التطبيق التجريبي للجلسة.يستخدم AndroidX Media3
androidx.media3.common.MediaItem
بدلاً من ذلك من MediaBrowserCompat.MediaItem وMediaMetadataCompat. قطع الغيار يجب تغيير رمزك المرتبط بالفئات القديمة وفقًا لذلك أو الربط بـ Media3MediaItem
بدلاً من ذلك.تم تغيير نموذج البرمجة غير المتزامنة العام إلى
Futures
في على عكس طريقةResult
القابلة للفصلMediaBrowserServiceCompat
يمكن أن يؤدي تنفيذ خدمتك إلى ظهور غير متزامنListenableFuture
بدلاً من فصل نتيجة أو إرجاع مستقبل مباشر لإرجاع قيمة مباشرةً.
إزالة 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، قد تظهر لك أخطاء أداة Lint حول الاستخدامات غير المستقرة لواجهة برمجة التطبيقات.
يمكن استخدام واجهات برمجة التطبيقات هذه بشكل آمن، كما أن أخطاء الوبر هي منتج ثانوي
يضمن التوافق الثنائي. إذا لم تكن تطلب برنامجًا ثنائيًا دقيقًا
التوافق، يمكن منع هذه الأخطاء بأمان باستخدام @OptIn
التعليق التوضيحي.
خلفية
لم يقدّم الإصدار 1 أو 2 من ExoPlayer ضمانات صارمة بشأن التوافق الثنائي. من المكتبة بين الإصدارات اللاحقة. تعتبر واجهة برمجة التطبيقات ExoPlayer مهمة جدًا كبيرة من حيث التصميم، للسماح للتطبيقات بتخصيص كل جانب من جوانب التشغيل. وتقدم الإصدارات اللاحقة من ExoPlayer رمزًا إعادة التسمية أو التغييرات الأخرى التي قد تؤدي إلى أعطال (مثل إضافة طرق جديدة مطلوبة على الواجهات) ضِمن وفي معظم الحالات، يتم التخفيف من حدة هذه الانقطاعات من خلال إدخال الرمز الجديد إلى جانب إيقاف الرمز القديم لبعض الإصدارات، وذلك للسماح للمطوّرين المستخدم لنقل بيانات الاستخدام، إلا أن هذا لم يكن ممكنًا دائمًا.
أدّت هذه التغييرات التي قد تؤدي إلى عطل إلى حدوث مشكلتَين لمستخدمي الإصدار الأول من ExoPlayer. ومكتبات الإصدار 2:
- وقد تؤدي الترقية من إصدار ExoPlayer إلى إيقاف تجميع الرمز.
- يشير هذا المصطلح إلى تطبيق يعتمد على ExoPlayer بشكل مباشر أو من خلال حساب متوسط. المكتبة يجب أن يتأكد من أن كلا التبعيتين كانتا نفس الإصدار، وإلا فقد يؤدي عدم التوافقات الثنائية إلى حدوث أعطال في وقت التشغيل.
التحسينات في Media3
تضمن منصة Media3 التوافق الثنائي مع مجموعة فرعية من مساحة عرض واجهة برمجة التطبيقات. تشير رسالة الأشكال البيانية
يتم وضع علامة على الأجزاء التي لا تضمن التوافق الثنائي معها
@UnstableApi
ولتوضيح هذا التمييز، فإنّ الاستخدامات غير المستقرة
تؤدي رموز واجهة برمجة التطبيقات إلى إنشاء خطأ في الوبر ما لم تتم إضافة تعليقات توضيحية إليها باستخدام @OptIn
.
بعد النقل من الإصدار الثاني من ExoPlayer إلى Media3، قد تظهر لك رسائل واجهة برمجة تطبيقات غير مستقرة. الأخطاء في الوبر. قد يجعل هذا الأمر يبدو أن Media3 "أقل ثباتًا" من ExoPlayer الإصدار 2. ولكن الأمر ليس كذلك. كلمة 'غير مستقرة' لا تختلف جزأين من واجهة برمجة تطبيقات Media3 مستوى الثبات ككامل مساحة واجهة برمجة التطبيقات ExoPlayer v2 لا تتوفر ضمانات لمساحة واجهة برمجة تطبيقات Media3 الثابتة في الإصدار 2 من ExoPlayer على الكل. يكمن الاختلاف في أن خطأ الوبر ينبهك الآن إلى ومستويات الاستقرار.
معالجة أخطاء أداة Lint غير الثابتة لواجهة برمجة التطبيقات
راجع قسم تحرّي الخلل وإصلاحه ضمن أخطاء الوبر هذه للحصول على تفاصيل حول كيفية
إضافة تعليقات توضيحية حول استخدامات Java وKotlin لواجهات برمجة التطبيقات غير الثابتة باستخدام @OptIn
واجهات برمجة التطبيقات التي تم إيقافها نهائيًا
قد تلاحظ أن طلبات البيانات من واجهات برمجة التطبيقات المتوقّفة نهائيًا قد تم إيقافها في نظام Android. استوديو YouTube. نقترح استبدال هذه المكالمات بالبديل المناسب. مرِّر مؤشر الماوس فوق الرمز لعرض JavaDoc الذي يحدد واجهة برمجة التطبيقات التي يجب استخدامها بدلاً من ذلك.
عيّنات التعليمات البرمجية والتطبيقات التجريبية
- التطبيق التجريبي لجلسة AndroidX Media3 (الأجهزة الجوّالة وWearOS)
- الإجراءات المخصّصة
- إشعار واجهة مستخدم النظام، MediaButton/BT
- التحكّم في التشغيل باستخدام "مساعد Google"
- UAMP: Android Media Player (branch media3) (الأجهزة الجوّالة، AutomotiveOS)
- إشعار واجهة مستخدم النظام، MediaButton/BT، استئناف التشغيل
- عنصر التحكّم في التشغيل على نظام التشغيل Wear OS أو "مساعد Google"
- AutomotiveOS: الطلب المخصَّص وتسجيل الدخول