إضافة توافق نظام التشغيل Android Automotive إلى تطبيق الوسائط

يتيح نظام التشغيل Android Automotive للمستخدمين تثبيت التطبيقات في السيارة. للوصول إلى مستخدمي هذا النظام الأساسي، عليك توزيع تطبيق ملائم لقائدي السيارات يتوافق مع نظام التشغيل Android Automotive. يمكنك إعادة استخدام جميع الرموز البرمجية والموارد تقريبًا في تطبيق Android Auto، ولكن عليك إنشاء إصدار منفصل يفي بالمتطلبات الواردة في هذه الصفحة.

نظرة عامة على التطوير

لا تتطلّب إضافة نظام التشغيل Android Automotive سوى بضع خطوات، كما هو موضّح في الأقسام التالية:

  1. تفعيل ميزات السيارات في "استوديو Android"
  2. أنشئ وحدة للسيارات.
  3. تعديل تبعيات Gradle
  4. يمكنك اختياريًا تنفيذ الإعدادات وأنشطة تسجيل الدخول.

اعتبارات التصميم

يتولى نظام التشغيل Android Automotive مسؤولية تنسيق محتوى الوسائط الذي يتلقّاه من خدمة متصفح الوسائط في تطبيقك. وهذا يعني أنّ تطبيقك لا يرسم واجهة المستخدم ولا يبدأ أيًا من أنشطتك عندما يقوم المستخدم بتشغيل الوسائط.

في حال تنفيذ إعدادات أو أنشطة تسجيل الدخول، يجب أن تكون هذه الأنشطة محسَّنة للمركبة. ارجع إلى إرشادات التصميم الخاصة بنظام التشغيل Android Automotive أثناء تصميم تلك العناصر من تطبيقك.

إعداد مشروعك

يجب إعداد عدة أجزاء من مشروع تطبيقك لإتاحة التوافق مع نظام التشغيل Android Automotive.

تفعيل ميزات السيارات في "استوديو Android"

استخدِم الإصدار 4.0 من "استوديو Android" أو الإصدارات الأحدث لضمان تفعيل كل ميزات نظام التشغيل Automotive.

إنشاء وحدة خاصة بالسيارات

بعض مكوّنات نظام التشغيل Android Automotive، مثل البيان، لها متطلبات خاصة بنظام التشغيل. أنشئ وحدة يمكنها الاحتفاظ بالرمز البرمجي لهذه المكونات منفصلاً عن التعليمات البرمجية الأخرى في مشروعك، مثل الكود المستخدم لتطبيق الهاتف.

اتبع هذه الخطوات لإضافة وحدة سيارات إلى مشروعك:

  1. في استوديو Android، انقر على ملف > جديد > وحدة جديدة.
  2. اختَر وحدة سيارات، ثم انقر على التالي.
  3. أدخِل اسم التطبيق/المكتبة. هذا هو الاسم الذي يراه المستخدمون لتطبيقك على نظام التشغيل Android Automotive.
  4. أدخِل اسم الوحدة.
  5. عدِّل اسم الحزمة ليتطابق مع تطبيقك.
  6. اختَر واجهة برمجة التطبيقات 28: Android 9.0 (Pie) من أجل الحد الأدنى لحزمة تطوير البرامج (SDK)، ثم انقر على التالي.

    تعمل جميع السيارات التي تعمل بنظام التشغيل Android Automotive على Android 9 (المستوى 28 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث، لذا فإن اختيار هذه القيمة يستهدف جميع السيارات المتوافقة.

  7. اختَر بدون نشاط، ثم انقر على إنهاء.

بعد إنشاء الوحدة في "استوديو Android"، افتح AndroidManifest.xml في وحدة السيارات الجديدة:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.media">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" />

    <uses-feature
        android:name="android.hardware.type.automotive"
        android:required="true" />

</manifest>

يحتوي عنصر application على بعض المعلومات العادية عن التطبيق بالإضافة إلى عنصر uses-feature يعلن عن توافقه مع نظام التشغيل Android Automotive. يُرجى العلم بأنّه لا توجد أنشطة معرَّفة في البيان.

في حال نفَّذت الإعدادات أو أنشطة تسجيل الدخول، يمكنك إضافتها هنا. يبدأ النظام هذه الأنشطة باستخدام أغراض صريحة، وهي الأنشطة الوحيدة التي تُفصح عنها في بيان تطبيق Android Automotive.

بعد إضافة أي إعدادات أو أنشطة تسجيل الدخول، أكمل ملف البيان من خلال ضبط السمة android:appCategory="audio" في العنصر application وإضافة عناصر uses-feature التالية:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.media">

    <application
        android:allowBackup="true"
        android:appCategory="audio"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" />

    <uses-feature
        android:name="android.hardware.type.automotive"
        android:required="true" />

    <uses-feature
        android:name="android.hardware.wifi"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.screen.portrait"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.screen.landscape"
        android:required="false" />

</manifest>

ويضمن ضبط هذه الميزات صراحةً على required="false" عدم تعارض تطبيقك مع ميزات الأجهزة المتاحة في الأجهزة التي تعمل بنظام التشغيل Automotive.

توضيح إتاحة الوسائط لنظام التشغيل Android Automotive

استخدِم إدخال البيان التالي لتوضيح أنّ تطبيقك يتوافق مع نظام التشغيل Android Automotive:

<application>
    ...
    <meta-data android:name="com.android.automotive"
        android:resource="@xml/automotive_app_desc"/>
    ...
</application>

يشير إدخال البيان هذا إلى ملف XML الذي يوضِّح إمكانيات السيارات التي يوفّرها تطبيقك.

للإشارة إلى أنّ لديك تطبيق وسائط، أضِف ملف XML باسم automotive_app_desc.xml إلى دليل res/xml/ في مشروعك. ضمِّن المحتوى التالي في هذا الملف:

<automotiveApp>
    <uses name="media"/>
</automotiveApp>

فلاتر الأهداف

يستخدم نظام التشغيل Android Automotive أهدافًا صريحة لبدء الأنشطة في تطبيق الوسائط الخاص بك. يُرجى عدم تضمين أي أنشطة تحتوي على فلاتر أهداف CATEGORY_LAUNCHER أو ACTION_MAIN في ملف البيان.

عادةً ما تستهدف الأنشطة مثل النشاط الوارد في المثال التالي هاتفًا أو جهازًا جوّالاً آخر. اذكر هذه الأنشطة في الوحدة التي تنشئ تطبيق الهاتف، وليس في الوحدة التي تنشئ تطبيق نظام التشغيل Android Automotive.

<activity android:name=".MyActivity">
    <intent-filter>
        <!-- You can't use either of these intents for Android Automotive OS -->
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <!--
        In their place, you can include other intent filters for any activities
        that your app needs for Android Automotive OS, such as settings or
        sign-in activities.
        -->
    </intent-filter>
</activity>

تعديل تبعيات Gradle

وننصحك بالاحتفاظ بخدمة متصفح الوسائط في وحدة منفصلة تشاركها بين تطبيق الهاتف ووحدة السيارات. إذا كنت تستخدم هذا المنهج، تحتاج إلى تحديث وحدة السيارات لتضمين الوحدة المشتركة، كما هو موضح في المقتطف التالي:

my-auto-module/build.gradle

رائع

buildscript {
    ...
    dependencies {
        ...
        implementation project(':shared_module_name')
    }
}

Kotlin

buildscript {
    ...
    dependencies {
        ...
        implementation(project(":shared_module_name"))
    }
}

تطبيق الإعدادات وأنشطة تسجيل الدخول

بالإضافة إلى خدمة متصفح الوسائط، يمكنك أيضًا توفير إعدادات محسّنة للمركبة وأنشطة تسجيل الدخول لتطبيق نظام التشغيل Android Automotive. تتيح لك هذه الأنشطة توفير وظائف التطبيق غير المضمّنة في واجهات برمجة تطبيقات وسائط Android.

لا تنفذ هذه الأنشطة إلا إذا كان تطبيق نظام التشغيل Android Automotive بحاجة إلى السماح للمستخدمين بتسجيل الدخول أو تحديد إعدادات التطبيق. لا يستخدم Android Auto هذه الأنشطة.

مهام سير عمل النشاط

يوضِّح المخطّط التالي كيفية تفاعل المستخدم مع إعداداتك وأنشطة تسجيل الدخول باستخدام نظام التشغيل Android Automotive:

سير العمل لأنشطة الإعدادات وتسجيل الدخول

الشكل 1. مهام سير عمل نشاط تسجيل الدخول والإعدادات

الحد من مصادر تشتيت الانتباه في الإعدادات وأنشطة تسجيل الدخول

للتأكّد من أنّ الإعدادات و/أو أنشطة تسجيل الدخول غير متاحة إلا للاستخدام أثناء ركن سيارة المستخدم، يُرجى التحقّق من أنّ عناصر <activity> لا تتضمّن عنصر <meta-data> التالي. وسيتم رفض تطبيقك أثناء المراجعة في حال وجود هذا العنصر.

<!-- NOT ALLOWED -->
<meta-data
  android:name="distractionOptimized"
  android:value="true"/>

إضافة نشاط إعدادات

يمكنك إضافة نشاط إعدادات محسّنة للمركبة حتى يتمكن المستخدمون من ضبط إعدادات تطبيقك في سياراتهم. يمكن أن يوفر نشاط الإعدادات أيضًا مهام سير عمل أخرى، مثل تسجيل الدخول إلى حساب مستخدم أو الخروج منه أو تبديل حسابات المستخدمين. تذكر أن هذا النشاط لا يتم تشغيله إلا عن طريق تطبيق يعمل على نظام التشغيل Android Automotive. لا تستخدمها تطبيقات الهاتف المرتبطة بـ Android Auto.

تعريف نشاط إعدادات

يجب الإفصاح عن نشاط الإعدادات في ملف بيان تطبيقك، كما هو موضَّح في مقتطف الرمز التالي:

<application>
    ...
    <activity android:name=".AppSettingsActivity"
              android:exported="true"
              android:theme="@style/SettingsActivity"
              android:label="@string/app_settings_activity_title">
        <intent-filter>
            <action android:name="android.intent.action.APPLICATION_PREFERENCES"/>
        </intent-filter>
    </activity>
    ...
</application>

تنفيذ نشاط الإعدادات

عندما يشغِّل المستخدم تطبيقك، يرصد نظام التشغيل Android Automotive نشاط الإعدادات الذي أعلنت عنه ويعرض الغرض من التطبيق، مثل رمز. يمكن للمستخدم النقر على هذا العنصر أو اختياره باستخدام شاشة سيارته للانتقال إلى النشاط. يرسل نظام التشغيل Android Automotive الغرض من ACTION_APPLICATION_PREFERENCES الذي يطلب من تطبيقك بدء نشاط الإعدادات.

ويوضّح الجزء المتبقي من هذا القسم كيفية تعديل الرمز البرمجي من نموذج تطبيق مشغّل موسيقى Android (UAMP) لتنفيذ نشاط إعدادات لتطبيقك.

للبدء، قم بتنزيل نموذج التعليمة البرمجية:

# Clone the UAMP repository
git clone https://github.com/android/uamp.git

# Fetch the appropriate pull request to your local repository
git fetch origin pull/323/head:NEW_LOCAL_BRANCH_NAME

# Switch to the new branch
git checkout NEW_LOCAL_BRANCH_NAME

لتنفيذ نشاطك، اتبع الخطوات التالية:

  1. انسخ مجلد automotive/automotive-lib إلى وحدة السيارات.
  2. حدِّد شجرة الإعدادات المفضّلة كما في automotive/src/main/res/xml/preferences.xml.
  3. نفِّذ عنصر PreferenceFragmentCompat يظهر فيه نشاط الإعدادات. يمكنك الاطّلاع على ملفَّي SettingsFragment.kt وSettingsActivity.kt في UAMP ودليل إعدادات Android للحصول على مزيد من المعلومات.

أثناء تنفيذ نشاط الإعدادات، ضع في اعتبارك أفضل الممارسات التالية لاستخدام بعض المكونات في مكتبة التفضيلات:

  • عدم وجود أكثر من مستويَين من العمق أسفل العرض الرئيسي في نشاط الإعدادات.
  • لا تستخدم DropDownPreference. يمكنك استخدام ListPreference بدلاً من ذلك.
  • العناصر التنظيمية:
    • PreferenceScreen
      • يجب أن يكون هذا هو المستوى الأعلى في شجرة الإعدادات المفضّلة.
    • PreferenceCategory
      • تُستخدَم هذه الوظيفة لتجميع عناصر Preference معًا.
      • تضمين title
  • عليك تضمين key وtitle في كل المكوّنات التالية. يمكنك أيضًا تضمين summary أو icon أو كليهما:
    • Preference
      • خصِّص المنطق في استدعاء onPreferenceTreeClick() لتنفيذ PreferenceFragmentCompat.
    • CheckBoxPreference
      • يمكن أن يتضمّن النص summaryOn أو summaryOff بدلاً من summary للنص الشرطي.
    • SwitchPreference
      • يمكن أن يتضمّن النص summaryOn أو summaryOff بدلاً من summary للنص الشرطي.
      • يمكن أن تتضمّن السمة switchTextOn أو switchTextOff.
    • SeekBarPreference
      • تضمين min وmax وdefaultValue
    • EditTextPreference
      • تضمين dialogTitle وpositiveButtonText وnegativeButtonText
      • يمكن أن تتضمّن السمة dialogMessage و/أو dialogLayoutResource.
    • com.example.android.uamp.automotive.lib.ListPreference
      • يشتق في الغالب من ListPreference.
      • يُستخدَم لعرض قائمة اختيار واحد من Preference عناصر.
      • يجب أن يحتوي على المصفوفة entries وentryValues المقابلة.
    • com.example.android.uamp.automotive.lib.MultiSelectListPreference
      • يشتق في الغالب من MultiSelectListPreference.
      • يُستخدَم لعرض قائمة خيارات متعددة من Preference عناصر.
      • يجب أن يحتوي على المصفوفة entries وentryValues المقابلة.

إضافة نشاط تسجيل دخول

إذا كان تطبيقك يتطلب من المستخدم تسجيل الدخول ليتمكّن من استخدام التطبيق، يمكنك إضافة نشاط تسجيل دخول محسَّن للمركبات يعالج تسجيل الدخول والخروج من التطبيق. ويمكنك أيضًا إضافة مسارات عمل لتسجيل الدخول والخروج إلى نشاط الإعدادات، واستخدام نشاط تسجيل دخول مخصّص إذا تعذّر استخدام التطبيق إلى أن يسجّل المستخدم الدخول. تذكر أن هذا النشاط لا يتم تشغيله إلا من خلال تطبيق يعمل على نظام التشغيل Android Automotive. لا تستخدمها تطبيقات الهاتف المرتبطة بميزة Android Auto.

يجب تسجيل الدخول عند بدء التطبيق.

لمطالبة المستخدم بتسجيل الدخول قبل أن يتمكن من استخدام تطبيقك، يجب أن تقوم خدمة متصفح الوسائط لديك بتنفيذ الإجراءات التالية:

  1. في طريقة onLoadChildren() الخاصة بخدمتك، أرسِل نتيجة null باستخدام الطريقة sendResult().
  2. اضبط PlaybackStateCompat لجلسة الوسائط على STATE_ERROR باستخدام الإجراء setState(). يؤدي ذلك إلى إعلام نظام التشغيل Android Automotive بأنّه لا يمكن إجراء أي عمليات أخرى إلا بعد إصلاح الخطأ.
  3. اضبط رمز الخطأ PlaybackStateCompat لجلسة الوسائط على ERROR_CODE_AUTHENTICATION_EXPIRED. يؤدي ذلك إلى إعلام نظام التشغيل Android Automotive بأنّ المستخدم بحاجة إلى المصادقة.
  4. اضبط رسالة خطأ PlaybackStateCompat لجلسة الوسائط باستخدام الطريقة setErrorMessage(). يُرجى أقلمة رسالة الخطأ هذه للّغة الحالية للمستخدم، لأنّ هذه الرسالة موجَّهة للمستخدم.
  5. اضبط الميزات الإضافية PlaybackStateCompat لجلسة الوسائط باستخدام الطريقة setExtras(). تضمين المفتاحين التاليين:

يوضِّح مقتطف الرمز التالي كيف يمكن أن يطلب تطبيقك من المستخدِم تسجيل الدخول قبل استخدام تطبيقك:

Kotlin

import androidx.media.utils.MediaConstants

val signInIntent = Intent(this, SignInActivity::class.java)
val signInActivityPendingIntent = PendingIntent.getActivity(this, 0,
    signInIntent, 0)
val extras = Bundle().apply {
    putString(
        MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL,
        "Sign in"
    )
    putParcelable(
        MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT,
        signInActivityPendingIntent
    )
}

val playbackState = PlaybackStateCompat.Builder()
        .setState(PlaybackStateCompat.STATE_ERROR, 0, 0f)
        .setErrorMessage(
            PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED,
            "Authentication required"
        )
        .setExtras(extras)
        .build()
mediaSession.setPlaybackState(playbackState)

Java

import androidx.media.utils.MediaConstants;

Intent signInIntent = new Intent(this, SignInActivity.class);
PendingIntent signInActivityPendingIntent = PendingIntent.getActivity(this, 0,
    signInIntent, 0);
Bundle extras = new Bundle();
extras.putString(
    MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL,
    "Sign in");
extras.putParcelable(
    MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT,
    signInActivityPendingIntent);

PlaybackStateCompat playbackState = new PlaybackStateCompat.Builder()
    .setState(PlaybackStateCompat.STATE_ERROR, 0, 0f)
    .setErrorMessage(
            PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED,
            "Authentication required"
    )
    .setExtras(extras)
    .build();
mediaSession.setPlaybackState(playbackState);

بعد مصادقة المستخدم بنجاح، اضبط PlaybackStateCompat على حالة أخرى غير STATE_ERROR، ثم أعِد المستخدم إلى نظام التشغيل Android Automotive من خلال استدعاء طريقة finish() للنشاط.

تنفيذ نشاط تسجيل الدخول

تقدّم Google مجموعة متنوعة من أدوات الهوية التي يمكنك استخدامها لمساعدة المستخدمين في تسجيل الدخول إلى تطبيقك في سياراتهم. توفر بعض الأدوات، مثل مصادقة Firebase، مجموعات أدوات كاملة يمكنها مساعدتك في إنشاء تجارب مصادقة مخصصة. تستفيد الأدوات الأخرى من بيانات الاعتماد الحالية للمستخدم أو التقنيات الأخرى لمساعدتك في إنشاء تجارب تسجيل دخول سلسة للمستخدمين.

يمكن أن تساعدك الأدوات التالية في إنشاء تجربة تسجيل دخول أسهل للمستخدمين الذين سجّلوا الدخول سابقًا على جهاز آخر:

  • تسجيل الدخول بخدمة "نقرة واحدة" والاشتراك فيها: إذا سبق أن نفّذت ميزة نقرة واحدة على أجهزة أخرى، مثل تطبيق الهاتف، يمكنك استخدامها في تطبيق نظام التشغيل Android Automotive لدعم المستخدمين الحاليين من خلال ميزة "نقرة واحدة".
  • تسجيل الدخول باستخدام حساب Google: إذا سبق لك تطبيق ميزة تسجيل الدخول باستخدام حساب Google على أجهزة أخرى، مثل تطبيق الهاتف، يمكنك استخدام ميزة "تسجيل الدخول بحساب Google" في تطبيق نظام التشغيل Android Automotive لإتاحة الميزة لمستخدمي ميزة "تسجيل الدخول بحساب Google" الحاليين.
  • الملء التلقائي من Google: إذا فعّل المستخدمون ميزة "الملء التلقائي من Google" على أجهزة Android الأخرى، يتم حفظ بيانات الاعتماد الخاصة بهم في مدير كلمات المرور في Google. عندما يسجّل هؤلاء المستخدمون الدخول إلى تطبيق نظام التشغيل Android Automotive، تقترح ميزة "الملء التلقائي من Google" بيانات الاعتماد المحفوظة ذات الصلة. لا يتطلب استخدام ميزة "الملء التلقائي من Google" أي جهد لتطوير التطبيقات. ومع ذلك، يمكن لمطوّري التطبيقات تحسين تطبيقاتهم للحصول على نتائج ذات جودة أفضل. تتوفّر ميزة "الملء التلقائي من Google" على جميع الأجهزة التي تعمل بنظام التشغيل Android 8.0 (المستوى 26 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث، بما في ذلك نظام التشغيل Android Automotive.

استخدام مدير الحساب

بالنسبة إلى تطبيقات نظام التشغيل Android Automotive التي تتضمَّن مصادقة، يجب أن تستخدم AccountManager للأسباب التالية:

  • تجربة أفضل للمستخدم وسهولة إدارة الحساب: يمكن للمستخدمين إدارة جميع حساباتهم بسهولة من قائمة الحسابات في إعدادات النظام، بما في ذلك تسجيل الدخول وتسجيل الخروج.
  • تجارب"الضيوف": السيارات هي أجهزة مشتركة، ما يعني أنّه يمكن للمصنّعين الأصليين للأجهزة تفعيل تجارب "الضيوف" في المركبة التي لا يمكن إضافة حسابات فيها. تم فرض هذا الحظر باستخدام DISALLOW_MODIFY_ACCOUNTS لـ AccountManager.

الأذونات

إذا كنت بحاجة إلى طلب أذونات من المستخدم، استخدِم المسار نفسه كنشاط المصادقة أو نشاط الإعدادات في الرسم البياني لسير عمل النشاط المعروض في قسم سابق.

خطأ أثناء المعالجة

يتم نقل الأخطاء في تطبيقات الوسائط على نظام التشغيل Android Automotive من خلال PlaybackStateCompat لجلسة الوسائط. بالنسبة إلى جميع الأخطاء، اضبط رمز خطأ ورسالة خطأ مناسبَين في PlaybackStateCompat. يؤدي هذا إلى ظهور Toast في واجهة المستخدم

عند حدوث خطأ ولكن يمكن متابعة التشغيل، أبلِغ خطأ غير جسيم. على سبيل المثال، قد يتمكن المستخدم من تشغيل الموسيقى في أحد التطبيقات قبل تسجيل الدخول، ولكن يتعين عليه تسجيل الدخول قبل أن يتمكن من تخطي أغنية. عند استخدام خطأ غير خطير، قد يقترح النظام تسجيل دخول المستخدم بدون مقاطعة التشغيل لعنصر الوسائط الحالي.

عند إصدار خطأ غير جسيم، يُرجى الاحتفاظ ببقية PlaybackStateCompat كما هي، باستثناء رمز الخطأ ورسالة الخطأ. يتيح استخدام هذا الأسلوب مواصلة تشغيل عنصر الوسائط الحالي بينما يقرّر المستخدم ما إذا كان يريد تسجيل الدخول.

عندما يتعذّر تشغيل المحتوى، مثلاً في حال عدم توفّر اتصال بالإنترنت وعدم توفّر محتوى بلا إنترنت، اضبط حالة PlaybackStateCompat على STATE_ERROR.

عند إجراء تعديلات لاحقة على PlaybackStateCompat، امحُ أي رموز خطأ ورسائل خطأ لتجنّب عرض تحذيرات متعدّدة للخطأ نفسه.

إذا تعذّر عليك في أي وقت تحميل شجرة تصفّح، على سبيل المثال، إذا كنت تطلب المصادقة ولم يسجّل المستخدم الدخول، يمكنك إرسال شجرة تصفّح فارغة. للدلالة على ذلك، اعرض نتيجة فارغة من onLoadChildren() لعقدة الوسائط الجذر. وعند حدوث ذلك، يعرض النظام خطأً بملء الشاشة مع رسالة الخطأ التي تم ضبطها في PlaybackStateCompat.

أخطاء قابلة للتنفيذ

إذا كان من الممكن اتخاذ إجراء بشأن الخطأ، يمكنك أيضًا ضبط العنصرَين الإضافيَين التاليَين في PlaybackStateCompat:

تظهر الأخطاء القابلة للتنفيذ على أنّها Dialog ويمكن للمستخدمين حلّها فقط عند إيقاف السيارة.

حالات خطأ في الاختبار

يُرجى التحقّق من أنّ تطبيقك يعالج الأخطاء في جميع السيناريوهات بسلاسة، بما في ذلك:

  • فئات مختلفة من منتجك: على سبيل المثال، فئات "مجانية" و"مميّزة" أو "مسجّلة الدخول" مقابل "تسجيل الخروج"
  • حالات القيادة المختلفة: على سبيل المثال، حالة ركن السيارة مقابل القيادة
  • حالات الاتصال المختلفة: على سبيل المثال، على الإنترنت مقارنةً بلا اتصال بالإنترنت

اعتبارات أخرى

ضع هذه الاعتبارات الأخرى في الاعتبار عند تطوير تطبيق نظام التشغيل Android Automotive:

المحتوى بلا إنترنت

استخدِم ميزة التشغيل بلا إنترنت، إن أمكن. من المتوقع أن تتوفّر في السيارات التي تعمل بنظام التشغيل Android Automotive إمكانية اتصال بيانات خاصة بها، ما يعني أنّ خطة البيانات مشمولة في تكلفة المركبة أو يدفع المستخدم مقابلها. ومع ذلك، من المتوقع أيضًا أن يكون لدى السيارات إمكانية اتصال المتغير أكثر من الأجهزة المحمولة.

إليك بعض الأشياء التي يجب وضعها في الاعتبار عند التفكير في استراتيجية الدعم في وضع عدم الاتصال:

  • أفضل وقت لتنزيل المحتوى هو عندما يكون تطبيقك قيد الاستخدام.
  • لا تفترض أنّ شبكة WiFi متاحة. قد لا تأتي السيارة إلى نطاق WiFi مطلقًا، أو ربما يكون المصنّع الأصلي للجهاز قد أوقف شبكة Wi-Fi لصالح شبكة خلوية.
  • على الرغم من أنه يمكنك التخزين المؤقت للمحتوى الذي يتوقع المستخدمون أن يستخدمه المستخدمون، ننصحك بالسماح للمستخدم بتغيير هذا السلوك من خلال نشاط الإعدادات.
  • تختلف مساحة القرص في السيارات، لذا يمكنك منح المستخدمين طريقة لحذف المحتوى بلا اتصال بالإنترنت، مثلاً من خلال خيار في نشاط الإعدادات.

دعم WebView

تتوفر مكوّنات WebView في نظام التشغيل Android Automotive، ولكن لا يُسمح لها إلا بإعداداتك وأنشطة تسجيل الدخول. يجب أن تحتوي الأنشطة التي تستخدم WebView على عنصر "إغلاق" أو "رجوع" خارج WebView.

في ما يلي بعض الأمثلة على حالات الاستخدام المقبولة لمكوّنات WebView:

  • عرض سياسة الخصوصية أو بنود الخدمة أو غير ذلك من الروابط ذات الصلة القانونية في نشاط الإعدادات.
  • تدفق مستند إلى الويب في نشاط تسجيل الدخول.

وعند استخدام مكوّن WebView، يمكنك تفعيل JavaScript.

تأمين WebView

اتخذ جميع الاحتياطات الممكنة للمساعدة في ضمان ألا يكون WebView نقطة دخول إلى شبكة الإنترنت الواسعة. اطّلِع على مقتطف الرمز التالي للاطّلاع على مثال عن كيفية قفل WebView بعنوان URL المستخدَم في طلب loadUrl() ومنع عمليات إعادة التوجيه. ننصحك بشدة بتنفيذ إجراءات وقائية كهذه عندما يكون ذلك ممكنًا، مثل عرض روابط ذات صلة بالقانون.

Kotlin

override fun shouldOverrideUrlLoading(webView: WebView,
                             webResourceRequest: WebResourceRequest): Boolean {
  val originalUri: Uri = Uri.parse(webView.originalUrl)
  // Check for allowed URLs
  if (originalUri.equals(Uri.parse(BLANK_URL))
      || originalUri.equals(webResourceRequest.url)) {
    return false
  }
  if (webResourceRequest.isRedirect) {
    logger.w("Redirect detected, not following")
    return true
  }
  setupWizardWebViewClientListener.onUriBlocked(webResourceRequest.url)
  logger.w(
    String.format(
      "Navigation prevented to %s original is %s", webResourceRequest.url, originalUri))
  return true
}

Java

@Override
public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest webResourceRequest) {
  Uri originalUri = Uri.parse(webView.getOriginalUrl());
  // Check for allowed URLs
  if (originalUri.equals(Uri.parse(BLANK_URL))
      || originalUri.equals(webResourceRequest.getUrl())) {
    return false;
  }
  if (webResourceRequest.isRedirect()) {
    logger.w("Redirect detected, not following");
    return true;
  }
  setupWizardWebViewClientListener.onUriBlocked(webResourceRequest.getUrl());
  logger.w(
      String.format(
          "Navigation prevented to %s original is %s", webResourceRequest.getUrl(), originalUri));
  return true;
}

أسماء الحِزم

بما أنّك توزّع ملف Android Package Kit (APK) منفصلاً لنظام التشغيل Android Automotive، يمكنك إعادة استخدام اسم الحزمة من تطبيقك للأجهزة الجوّالة أو إنشاء اسم حزمة جديد. إذا استخدمت اسم حزمة مختلفًا، سيحتوي تطبيقك على بطاقتَي بيانات منفصلتَين على "متجر Play". إذا أعدت استخدام اسم الحزمة الحالية، فإن تطبيقك يحتوي على قائمة واحدة عبر كلا النظامين الأساسيين.

يعتمد ذلك في الغالب على قرار تجاري. على سبيل المثال، إذا كان لديك فريق واحد يعمل على التطبيق للأجهزة الجوّالة وفريق منفصل يعمل على تطبيق نظام التشغيل Android Automotive، فعندئذٍ قد يكون من المنطقي استخدام أسماء حِزم منفصلة والسماح لكل فريق بإدارة بطاقة بياناته على "متجر Play". ليس هناك فرق كبير في الجهد الفني المطلوب لاستخدام أي من الأسلوبين.

يلخص الجدول التالي بعض الاختلافات الرئيسية الأخرى بين الاحتفاظ باسم الحزمة الحالي واستخدام اسم حزمة جديد:

الميزة اسم الحزمة نفسه اسم الحزمة الجديد
بطاقة بيانات المتجر بلوغ القاعدة الأولى عدة تعليقات
تركيب بمرآة المرآة نعم: "إعادة تثبيت التطبيق بسرعة" أثناء معالج الإعداد لا
عملية مراجعة "متجر Play" حظر المراجعات: إذا تعذّر إجراء المراجعة لملف APK واحد، يتم حظر حِزم APK الأخرى المرسَلة في الإصدار نفسه. المراجعات الفردية
الإحصاءات والمقاييس والوظائف الحيوية مجمّعة: يمكنك الفلترة للوصول إلى البيانات المتعلّقة بالسيارات. فصل
الفهرسة وترتيب البحث طوِّر وضعك الحالي لا يوجد تبديل
الدمج مع التطبيقات الأخرى لن تكون هناك حاجة على الأرجح إلى إجراء أي تغييرات، بافتراض أنّه تتم مشاركة رمز الوسائط بين ملفَّي APK. وقد تحتاج إلى تحديث التطبيق المعنيّ، مثل تشغيل معرّف الموارد المنتظم (URI) باستخدام "مساعد Google".

الأسئلة الشائعة

يُرجى الاطّلاع على الأقسام التالية للحصول على إجابات عن بعض الأسئلة الشائعة حول نظام التشغيل Android Automotive.

الأجهزة

هل يمكن لتطبيقي الوصول إلى الميكروفون؟

بالنسبة إلى التطبيقات التي تستهدف الإصدار 10 من نظام التشغيل Android (المستوى 29 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث، يُرجى مراجعة مستندات مشاركة إدخال الصوت. ولا يمكن إجراء ذلك قبل المستوى 29 من واجهة برمجة التطبيقات.

ما هي واجهات برمجة التطبيقات للسيارة التي يمكننا الوصول إليها وكيف؟

تقتصر على واجهات برمجة التطبيقات التي يعرضها المصنّع الأصلي للجهاز. ويجري تطوير العمليات لتوحيد طريقة الوصول إلى واجهات برمجة التطبيقات هذه.

يمكن للتطبيقات الوصول إلى واجهات برمجة تطبيقات السيارة من خلال SetProperty() وGetProperty() في CarPropertyManager. يمكنك الرجوع إلى رمز المصدر أو المستندات المرجعية للاطّلاع على قائمة بجميع المواقع المتاحة. إذا تمت إضافة تعليقات توضيحية إلى الموقع الإلكتروني باستخدام @SystemApi، سيقتصر على تطبيقات النظام المُحمَّلة مسبقًا.

ما هي أنواع برامج ترميز الصوت المتوافقة؟

راجِع تفاصيل برنامج ترميز الصوت في Android CDD.

هل برنامج Widevine DRM متاح؟

نعم. وهو متوافق مع Widevine DRM.

التطوير والاختبار

هل هناك أي قيود أو اقتراحات لاستخدام حِزم SDK والمكتبات التابعة لجهات خارجية؟

ولا تتوفّر لدينا أي إرشادات محدّدة حول استخدام حِزم SDK والمكتبات التابعة لجهات خارجية. إذا اخترت استخدام حِزم تطوير برامج (SDK) ومكتبات تابعة لجهات خارجية، ستظل مسؤولاً عن الالتزام بجميع متطلبات جودة تطبيقات السيارات.

هل يمكنني استخدام خدمة تعمل في المقدّمة؟

إنّ حالة الاستخدام الوحيدة المسموح بها للخدمة التي تعمل في المقدّمة هي تنزيل المحتوى للاستخدام بلا اتصال بالإنترنت. إذا كانت لديك حالة استخدام أخرى لخدمة تعمل في المقدّمة وتريد الحصول على دعم بشأنها، يمكنك التواصل معنا باستخدام مجموعة المناقشة الخاصة بنظام التشغيل Android Automotive.

نشر تطبيقات نظام التشغيل Android Automotive

كيف أنشر تطبيقي الذي يعمل بنظام التشغيل Android Automotive باستخدام Google Play Console؟

تتشابه عملية نشر التطبيق مع نشر تطبيق هاتف، ولكنك تستخدم شكلاً مختلفًا. لتفعيل تطبيقك من أجل استخدام شكل الجهاز في نظام التشغيل Android Automotive، يُرجى اتّباع الخطوات التالية:

  1. فتح Play Console
  2. اختيار تطبيقك
  3. من القائمة اليمنى، انقر على الإصدار > الإعداد > الإعدادات المتقدمة > أشكال الأجهزة.
  4. انقر على إضافة شكل الجهاز > نظام التشغيل Android Automotive، ثم اتّبِع التعليمات الواردة في Play Console.

مراجع إضافية

لمزيد من المعلومات حول نظام التشغيل Android Automotive، يُرجى الاطّلاع على المراجع الإضافية التالية.

العيّنات

الأدلّة

المدوّنات

الفيديوهات الطويلة

الإبلاغ عن مشكلة في وسائط نظام التشغيل Android Automotive

إذا واجهت مشكلة أثناء تطوير تطبيق الوسائط لنظام التشغيل Android Automotive، يمكنك الإبلاغ عنها باستخدام أداة تتبّع المشاكل من Google. احرص على ملء كل المعلومات المطلوبة في نموذج المشكلة.

إنشاء عدد جديد

قبل تقديم مشكلة جديدة، تحقّق مما إذا سبق أن تم الإبلاغ عنها في قائمة المشاكل. يمكنك الاشتراك والتصويت على المشكلات من خلال النقر على النجمة الخاصة بمشكلة في أداة التتبع. لمزيد من المعلومات، راجع الاشتراك في مشكلة.