افزودن پشتیبانی از «سیستم‌عامل Android Automotive» به برنامه رسانه

سیستم عامل Android Automotive به کاربران امکان می‌دهد برنامه در خودرو نصب کنند. برای جذب کاربران در این پلاتفرم، باید برنامه‌ای بهینه‌سازی‌شده برای راننده توزیع کنید که با سیستم عامل Android Automotive سازگار باشد. می‌توانید تقریباً از همه کدها و منابع دوباره در برنامه Android Auto استفاده کنید، اما باید ساخت جداگانه‌ای ایجاد کنید که الزامات این صفحه را برآورده کند.

نمای کلی توسعه

افزودن پشتیبانی از «سیستم عامل Android Automotive» فقط به چند مرحله نیاز دارد که در بخش‌های زیر شرح داده شده است:

  1. ویژگی‌های خودرویی را در «استودیو Android» فعال کنید.
  2. ماژول خودرویی ایجاد کنید.
  3. وابستگی‌های Gradle را به‌روز کنید.
  4. درصورت تمایل، تنظیمات و فعالیت‌های ورود به سیستم را پیاده‌سازی کنید.
  5. درصورت تمایل، نکات میزبان رسانه را بخوانید.

ملاحظات طراحی

سیستم عامل Android Automotive طرح‌بندی محتوای رسانه‌ای را که از سرویس مرورگر رسانه برنامه شما دریافت می‌کند برعهده دارد. این یعنی وقتی کاربر بازپخش رسانه را راه‌اندازی می‌کند، برنامه‌تان واسط کاربر را ترسیم نمی‌کند و هیچ‌کدام از فعالیت‌هایتان را شروع نمی‌کند.

اگر درحال پیاده‌سازی تنظیمات یا فعالیت‌های ورود به سیستم هستید، این فعالیت‌ها باید بهینه‌سازی‌شده برای خودرو باشند. هنگام طراحی آن بخش‌های برنامه‌تان، به رهنمودهای طراحی برای «سیستم‌عامل Android Automotive» مراجعه کنید.

راه‌اندازی پروژه

برای فعال کردن پشتیبانی از «سیستم‌عامل Android Automotive»، باید چندین بخش از پروژه برنامه‌تان را راه‌اندازی کنید.

فعال کردن ویژگی‌های خودرویی در «استودیو Android»

از Android Studio نسخه ۴.۰ یا بالاتر استفاده کنید تا مطمئن شوید همه ویژگی‌های Automotive OS فعال است.

ایجاد ماژول خودرویی

برخی‌از مؤلفه‌های سیستم عامل Android Automotive، مانند مانیفست، الزامات خاص پلاتفرم دارند. واحدی ایجاد کنید که بتواند کد این مؤلفه‌ها را از کدهای دیگر در پروژه‌تان، مثل کد استفاده‌شده برای برنامه تلفن، جدا نگه دارد.

برای افزودن ماژول خودرویی به پروژه، این مراحل را دنبال کنید:

  1. در «استودیو Android»، روی فایل > جدید > واحد جدید کلیک کنید.
  2. Automotive Module (ماژول خودرویی) را انتخاب کنید، سپس روی Next (بعدی) کلیک کنید.
  3. نام برنامه/کتابخانه را وارد کنید. این نامی است که کاربران برای برنامه شما در سیستم عامل Android Automotive می‌بینند.
  4. نام واحد را وارد کنید.
  5. نام بسته را طوری تنظیم کنید که با برنامه‌تان مطابقت داشته باشد.
  6. API 28: Android 9.0 (Pie)‎ را برای Minimum SDK انتخاب کنید، سپس روی Next کلیک کنید.

    همه خودروهایی که از «سیستم عامل Android Automotive» پشتیبانی می‌کنند، Android 9 (سطح میانای برنامه‌سازی کاربردی ۲۸) یا بالاتر را اجرا می‌کنند، بنابراین انتخاب این مقدار همه خودروهای سازگار را هدف‌یابی می‌کند.

  7. بدون فعالیت را انتخاب کنید و سپس روی پایان کلیک کنید.

پس‌از ایجاد ماژول در Android Studio، 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 عنصر <application> روی "audio" تکمیل کنید.

<application
  ...
  android:appCategory="audio" />

تعریف الزامات ویژگی

همه برنامه‌های ساخته‌شده برای سیستم عامل Android Automotive باید الزامات خاصی را برآورده کنند تا بتوانند بااستفاده از Google Play توزیع شوند. برای اطلاعات بیشتر، به برآورده کردن الزامات ویژگی Google Play مراجعه کنید.

اعلام پشتیبانی از رسانه در سیستم‌عامل 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')
    }
}

کاتلین

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

تنظیمات و فعالیت‌های ورود به سیستم را پیاده‌سازی کنید

علاوه‌بر سرویس مرورگر رسانه، می‌توانید تنظیمات و فعالیت‌های ورود به سیستم بهینه‌شده برای خودرو را نیز برای برنامه «سیستم عامل Android Automotive» خود ارائه دهید. این فعالیت‌ها به شما امکان می‌دهند کارکردهای برنامه‌ای را ارائه دهید که در میاناهای برنامه‌سازی کاربردی Android Media گنجانده نشده است.

فقط درصورتی این فعالیت‌ها را پیاده‌سازی کنید که برنامه Android Automotive OS شما باید به کاربران اجازه دهد به سیستم وارد شوند یا تنظیمات برنامه را مشخص کنند. Android Auto از این فعالیت‌ها استفاده نمی‌کند.

گردش کار فعالیت

نمودار زیر نشان می‌دهد که کاربر چگونه بااستفاده از «سیستم عامل Android Automotive» با تنظیمات و فعالیت‌های ورود به سیستم شما تعامل برقرار می‌کند:

جریان‌های کاری برای فعالیت‌های «تنظیمات» و «ورود به سیستم»

شکل ۱. تنظیمات و گردش کار فعالیت ورود به سیستم.

جلوگیری از حواس‌پرتی در تنظیمات و فعالیت‌های ورود به سیستم

برای اطمینان از اینکه تنظیمات و فعالیت‌های ورود به سیستم شما فقط زمانی برای استفاده دردسترس هستند که خودرو کاربر پارک شده است، بررسی کنید که عنصر(های) <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 را ارسال می‌کند که به برنامه شما می‌گوید فعالیت تنظیمات را شروع کند.

بقیه این بخش نشان می‌دهد که چگونه می‌توانید کد را از برنامه نمونه Universal Android Music Player (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
      • می‌تواند به‌جای summary برای نوشتار شرطی، summaryOn یا summaryOff داشته باشد.
    • SwitchPreference
      • می‌تواند به‌جای summary، summaryOn یا summaryOff برای نوشتار شرطی داشته باشد.
      • می‌تواند 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 جلسه رسانه را بااستفاده از روش setState() روی STATE_ERROR تنظیم کنید. این به «سیستم‌عامل Android Automotive» می‌گوید که تا زمانی که خطا برطرف نشده است، هیچ عملیات دیگری نمی‌تواند انجام شود.
  3. کد خطای PlaybackStateCompat جلسه رسانه را روی ERROR_CODE_AUTHENTICATION_EXPIRED تنظیم کنید. این به سیستم عامل Android Automotive می‌گوید که کاربر باید اصالت‌سنجی کند.
  4. پیام خطای PlaybackStateCompat جلسه رسانه را بااستفاده از روش setErrorMessage() تنظیم کنید. چون این پیام خطا سَمت کاربر است، آن را برای منطقه زبانی فعلی کاربر بومی‌سازی کنید.
  5. PlaybackStateCompat اضافی جلسه رسانه را بااستفاده از روش setExtras() تنظیم کنید. دو یا سه کلید زیر را اضافه کنید:

    • PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL: رشته‌ای که روی دکمه‌ای که گردش کار ورود به سیستم را آغاز می‌کند نمایش داده می‌شود. چون این رشته سَمت کاربر است، آن را برای منطقه زبانی فعلی کاربر بومی‌سازی کنید.
    • PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT: PendingIntent که وقتی کاربر روی دکمه‌ای که PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL به آن اشاره می‌کند تک‌ضرب می‌زند، کاربر را به فعالیت ورود به سیستم شما هدایت می‌کند.
    • PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_USING_CAR_APP_LIBRARY_INTENT: یک PendingIntent که کاربر را به فعالیت ورود به سیستم «کتابخانه برنامه‌های ماشین» شما هدایت می‌کند. ازآنجایی‌که میزبان Car App Library برای رانندگی بهینه‌سازی شده است، هدف به‌طور خودکار از صفحه رفع خطا عبور می‌کند و فوراً صفحه ورود به سیستم شما را نمایش می‌دهد. اگر این ویژگی اضافی را تنظیم کردید، دو ویژگی اضافی قبلی را هم تنظیم کنید تا از سازگاری با نسخه‌های قدیمی‌تر خودروهای قدیمی‌تر مطمئن شوید.

تکه‌کد زیر نشان می‌دهد که چگونه برنامه‌تان می‌تواند کاربر را ملزم کند قبل‌از استفاده از برنامه‌تان به سیستم وارد شود:

کاتلین

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)

جاوا

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 برگردانید، سپس با فراخوانی روش finish() فعالیت، کاربر را به Android Automotive OS برگردانید.

پیاده‌سازی فعالیت ورود به سیستم

Google ابزارهای هویتی متنوعی ارائه می‌دهد که می‌توانید از آن‌ها برای کمک به کاربران در ورود به سیستم برنامه‌تان در خودروهایشان استفاده کنید. برخی‌از ابزارها، مانند Firebase Authentication، کیت‌های ابزار پشته کامل ارائه می‌دهند که می‌توانند به شما در ساختن تجربه‌های اصالت‌سنجی سفارشی کمک کنند. ابزارهای دیگر از اطلاعات کاربری موجود کاربر یا فناوری‌های دیگر استفاده می‌کنند تا به شما کمک کنند تجربه‌های ورود به سیستم یکپارچه‌ای برای کاربران بسازید.

ابزارهای زیر می‌توانند به شما کمک کنند تجربه ورود به سیستم آسان‌تری برای کاربرانی که قبلاً در دستگاه دیگری به سیستم وارد شده‌اند بسازید:

  • ورود به سیستم و ثبت‌نام با یک ضربه: اگر قبلاً ورود با یک ضربه را برای دستگاه‌های دیگر، مثل برنامه تلفن، پیاده‌سازی کرده‌اید، آن را برای برنامه Android Automotive OS خود نیز پیاده‌سازی کنید تا از کاربران فعلی «ورود با یک ضربه» پشتیبانی کنید.
  • ورود به سیستم با Google: اگر قبلاً ورود به سیستم با Google را برای دستگاه‌های دیگر، مثل برنامه تلفن، پیاده‌سازی کرده‌اید، «ورود به سیستم با Google» را برای برنامه Android Automotive OS خود پیاده‌سازی کنید تا از کاربران فعلی «ورود به سیستم با Google» پشتیبانی کنید.
  • تکمیل خودکار با Google: اگر کاربران در دیگر دستگاه‌های Android خود با «تکمیل خودکار با Google» موافقت کرده باشند، اطلاعات کاربری آن‌ها در مدیر گذرواژه Google ذخیره می‌شود. وقتی این کاربران به سیستم برنامه «سیستم‌عامل Android Automotive» شما وارد می‌شوند، «تکمیل خودکار با Google» اعتبارنامه‌های ذخیره‌شده مربوطه را پیشنهاد می‌دهد. استفاده از «تکمیل خودکار با Google» به تلاش برای توسعه برنامه نیاز ندارد. بااین‌حال، توسعه‌دهندگان برنامه می‌توانند برنامه‌هایشان را برای نتایج با کیفیت بهتر بهینه‌سازی کنند. همه دستگاه‌های دارای Android 8.0 (سطح میانای برنامه‌سازی کاربردی ۲۶) یا بالاتر، ازجمله «سیستم‌عامل Android Automotive»، از «تکمیل خودکار با Google» پشتیبانی می‌کنند.

استفاده از AccountManager

برنامه‌های سیستم عامل Android Automotive که اصالت‌سنجی دارند باید به‌دلایل زیر از AccountManager استفاده کنند:

  • تجربه کاربری بهتر و مدیریت آسان‌تر حساب: کاربران می‌توانند همه حساب‌هایشان را از منو حساب‌ها در تنظیمات سیستم مدیریت کنند، ازجمله ورود به سیستم و خروج از سیستم.
  • تجربه‌های «مهمان»: خودروها دستگاه‌های مشترک هستند، یعنی سازندگان اصلی تجهیزات می‌توانند تجربه‌های «مهمان» را در خودرو فعال کنند که در آن حساب‌ها نمی‌توانند اضافه شوند. این محدودیت بااستفاده از DISALLOW_MODIFY_ACCOUNTS برای AccountManager اعمال می‌شود.

اجازه‌ها

اگر لازم است از کاربر درخواست اجازه کنید، از همان جریان فعالیت اصالت‌سنجی یا فعالیت تنظیمات در نمودار گردش کار فعالیت که در بخش قبلی نشان داده شده است استفاده کنید.

پیاده‌سازی خروج از سیستم

صرف‌نظر از اینکه چگونه ورود به سیستم را پیاده‌سازی کرده‌اید، وقتی کاربر از سیستم خارج می‌شود، باید MediaBrowserServiceCompat#notifyChildrenChanged(rootId) را فراخوانی کنید تا درخت مرور شما را باطل کند تا برنامه میزبان رسانه هرگونه اطلاعات مربوط به کاربر (مانند جدیدترین پُرسمان جستجو) را پاک کند.

برنامه میزبان رسانه را شروع کنید

می‌توانید هدف‌هایی ایجاد کنید تا برنامه میزبان رسانه را در برنامه شما یا محتوای درون برنامه شما باز کند. برای مثال:

  • برنامه شما می‌تواند اعلانی با قصد معوق پست کند که به کاربر اجازه می‌دهد برنامه شما را برای گوش دادن به محتوای جدیدی باز کند.
  • برنامه شما می‌تواند پیوندهای عمیق را مدیریت کند و برنامه میزبان را در مناسب‌ترین نما باز کند.

تعیین قابلیت‌های میزبان رسانه

نسخه‌های برنامه میزبان رسانه از قابلیت‌های مختلفی پشتیبانی می‌کنند. میزبان‌ها با گنجاندن فیلترهای قصد برای کنش‌های قصد زیر، پشتیبانی از قابلیت‌های مختلف را نشان می‌دهند:

همه برنامه‌های میزبان رسانه از هدف‌های MEDIA_TEMPLATE پشتیبانی می‌کنند. برای تعیین اینکه آیا میزبان رسانه از هدف‌های MEDIA_TEMPLATE_V2 پشتیبانی می‌کند یا نه، می‌توانید از queryIntentActivities() به‌صورت زیر استفاده کنید:

val isMediaTemplateV2Supported = packageManager.queryIntentActivities(
  Intent(MediaIntentExtras.ACTION_MEDIA_TEMPLATE_V2),
  //  MATCH_DEFAULT_ONLY  since the host should be started with implicit intents
  //  MATCH_SYSTEM_ONLY  excludes any apps that aren't preinstalled
  PackageManager.MATCH_DEFAULT_ONLY or PackageManager.MATCH_SYSTEM_ONLY
).size > 0

ساختن و استفاده کردن از قصد

بسته به اینکه کدام کنش‌های هدف توسط میزبان رسانه پشتیبانی می‌شود و مورد استفاده خاص شما چیست، می‌توانید هنگام ساختن هدفی که برای راه‌اندازی برنامه میزبان رسانه استفاده می‌کنید، موارد اضافی زیر را ارائه دهید.

کلید اضافی نوع شرح کنش‌های پشتیبانی‌شده
EXTRA_KEY_MEDIA_COMPONENT String نام مؤلفه مسطح‌شده MediaBrowserService که برنامه میزبان رسانه باید به آن متصل شود – معمولاً نام مؤلفه برنامه شما. اگر این مورد اضافی مشخص نشده باشد، میزبان رسانه به‌طور پیش‌فرض به منبع رسانه فعال متصل می‌شود. MEDIA_TEMPLATE، MEDIA_TEMPLATE_V2
EXTRA_KEY_SEARCH_QUERY String پرسمان جستجویی که هنگام تماس استفاده می‌شود MEDIA_TEMPLATE، MEDIA_TEMPLATE_V2
EXTRA_KEY_MEDIA_ID String شناسه رسانه برای باز کردن در نمای مرور. MEDIA_TEMPLATE_V2
EXTRA_KEY_SEARCH_ACTION Integer کنشی که باید پس‌از تکمیل جستجوی EXTRA_KEY_SEARCH_QUERY انجام شود. MEDIA_TEMPLATE_V2

برای مثال، با میزبانی که از کنش‌های MEDIA_TEMPLATE_V2 پشتیبانی می‌کند، کد زیر برنامه میزبان رسانه را باز می‌کند، آن را به MyMediaBrowserService متصل می‌کند، جستجویی برای «Jazz» انجام می‌دهد، و سپس اولین مورد را از نتایج جستجو پخش می‌کند. در همه میزبان‌های دیگر، فقط برنامه میزبان رسانه را باز می‌کند و «جاز» را جستجو می‌کند و انتخاب کردن موردی برای پخش از نتایج را به کاربر واگذار می‌کند.

val startMediaHostIntent = Intent(ACTION_MEDIA_TEMPLATE)
  .putExtra(MediaIntentExtras.EXTRA_KEY_MEDIA_COMPONENT, MyMediaBrowserService::class.java)
  .putExtra(MediaIntentExtras.EXTRA_KEY_SEARCH_QUERY, "Jazz")
  .putExtra(MediaIntentExtras.EXTRA_KEY_SEARCH_ACTION, MediaIntentExtras.EXTRA_VALUE_PLAY_FIRST_ITEM_FROM_SEARCH)

context.startActivity(startMediaHostIntent)

برای بهبود تجربه برنامه رسانه‌تان در دستگاه‌های Android Automotive OS، می‌توانید پشتیبانی از پیوندهای عمیق را به برنامه‌تان اضافه کنید. برای مثال، این کار به کاربران اجازه می‌دهد برنامه‌تان را مستقیماً از مرورگر باز کنند یا وقتی نشانی وب هم‌رسانی‌شده از تلفن را بااستفاده از هم‌رسانی سریع دریافت می‌کنند، برنامه‌تان را باز کنند.

افزودن فیلترهای هدف پیوند عمیق

برای اینکه به سیستم‌عامل اطلاع دهید برنامه‌تان می‌تواند پیوندهای عمیق را مدیریت کند، باید فعالیت‌هایی با فیلترهای قصد مناسب داشته باشد. برای راهنمایی درباره قالب فیلترهای هدف استفاده‌شده برای پیوندهای عمیق، به افزودن فیلترهای هدف برای پیوندهای ورودی مراجعه کنید.

برای ارائه بهترین تجربه کاربری، از همه پیوندهای عمیقی که برنامه تلفن همراهتان پشتیبانی می‌کند پشتیبانی کنید، البته اگر برنامه درون خودرو شما بتواند به‌طور منطقی از آن‌ها پشتیبانی کند. اگر برنامه شما فعالیت‌های تنظیمات یا ورود به سیستم دارد، فیلترهای هدف برای مدیریت تنظیمات و پیوندهای عمیق ورود به سیستم باید در عناصر مانیفست <activity> مربوطه اعلام شوند. برای پخش رسانه و مرور پیوندهای عمیق، می‌توانید از فعالیت جَستانه استفاده کنید (در ادامه این بخش توضیح داده شده است).

برای راهنمایی درباره نحوه خواندن و واکنش نشان دادن به قصدی که برای شروع فعالیت برنامه‌تان استفاده شده است، به خواندن داده‌ها از قصد‌های ورودی مراجعه کنید.

Because the UI for browsing and playback is drawn by the host app, the activity used to handle deep links for playback and browsing actions shouldn't have any UI of its own.

درعوض، باید عمدتاً برای ساختن و استفاده از قصدی برای راه‌اندازی برنامه میزبان رسانه استفاده شود. درصورت لزوم، می‌تواند هرگونه تغییرات اضافی در وضعیت برنامه شما را نیز مدیریت کند، مانند افزودن موارد رسانه‌ای به صف. قطعه کد زیر نمونه‌ای از پیاده‌سازی فعالیت جَستانه را نشان می‌دهد:

fun DeepLinkTrampolineActivity : ComponentActivity() {

  override fun onCreate() {
    handleIntent(intent)
  }

  override fun onNewIntent(intent: Intent) {
    handleIntent(intent)
  }

  private fun handleIntent(intent: Intent) {
    // Handle any side effects, such as adding a song to the queue
    ...
    // Build the intent used to start the media host app
    val startMediaHostIntent = ...
    startActivity(intent)
    // Finish the activity immediately so it isn't shown on screen
    finish()
  }
}

خواندن نکات میزبان رسانه

بسته به برنامه سیستم (ازجمله نسخه آن) که به سرویس مرورگر رسانه شما متصل می‌شود، ممکن است برنامه‌تان موارد اضافی زیر را دریافت کند:

مدیریت کردن خطا

خطاهای برنامه‌های رسانه‌ای در «سیستم‌عامل Android Automotive» بااستفاده از PlaybackStateCompat جلسه رسانه منتقل می‌شوند. برای همه خطاها، کد خطا و پیام خطای مناسبی در PlaybackStateCompat تنظیم کنید. این کار باعث می‌شود Toast در میانای کاربری ظاهر شود.

وقتی خطایی رخ می‌دهد اما بازپخش می‌تواند ادامه یابد، خطای غیرمهلک صادر کنید. برای مثال، ممکن است کاربر بتواند قبل‌از ورود به سیستم، در برنامه‌ای موسیقی پخش کند، اما برای رد کردن آهنگ باید به سیستم وارد شود. وقتی از خطای غیرمهلک استفاده می‌کنید، سیستم می‌تواند به کاربر پیشنهاد دهد که بدون قطع کردن بازپخش فایل رسانه‌ای فعلی به سیستم وارد شود.

وقتی خطای غیرکشنده‌ای صادر می‌کنید، بقیه PlaybackStateCompat را همان‌طور که هست حفظ کنید، به‌جز کد خطا و پیام خطا. بااستفاده از این رویکرد، بازپخش فایل رسانه‌ای فعلی می‌تواند ادامه یابد درحالی‌که کاربر تصمیم می‌گیرد به سیستم وارد شود یا نه.

وقتی بازپخش ممکن نیست، مثلاً وقتی اتصال اینترنت وجود ندارد و محتوای آفلاین دردسترس نیست، وضعیت PlaybackStateCompat را روی STATE_ERROR تنظیم کنید.

در به‌روزرسانی‌های بعدی PlaybackStateCompat، همه کدهای خطا و پیام‌های خطا را پاک کنید تا از نمایش چندین هشدار برای یک خطا جلوگیری شود.

اگر در هر نقطه‌ای نتوانستید درخت مرور را بار کنید (مثلاً اگر به اصالت‌سنجی نیاز دارید و کاربر به سیستم وارد نشده است)، درخت مرور خالی ارسال کنید. برای نشان دادن این موضوع، نتیجه تهی را از onLoadChildren() برای گره رسانه ریشه برگردانید. وقتی این اتفاق می‌افتد، سیستم خطای تمام‌صفحه‌ای را با پیام خطای تنظیم‌شده در PlaybackStateCompat نمایش می‌دهد.

خطاهای قابل‌اقدام

اگر خطا قابل‌اجرا است، دو مورد اضافی زیر را نیز در PlaybackStateCompat تنظیم کنید:

خطاهای قابل‌اقدام به‌صورت Dialog نشان داده می‌شوند و کاربران فقط وقتی خودرو متوقف است می‌توانند آن‌ها را برطرف کنند.

آزمایش کردن موارد خطا

درستی‌سنجی کنید که برنامه‌تان خطاها را در همه سناریوها به‌درستی مدیریت می‌کند، ازجمله:

  • سطوح مختلف محصول شما: برای مثال، رایگان درمقابل پولی یا واردشده به سیستم درمقابل خارج‌شده از سیستم
  • حالت‌های مختلف رانندگی: برای مثال، پارک‌شده درمقابل درحال رانندگی
  • وضعیت‌های مختلف اتصال‌پذیری: برای مثال، آنلاین درمقابل آفلاین

ملاحظات دیگر

هنگام توسعه برنامه «سیستم‌عامل Android Automotive»، این ملاحظات دیگر را درنظر داشته باشید:

محتوای آفلاین

درصورت لزوم، پشتیبانی از بازپخش آفلاین را پیاده‌سازی کنید. انتظار می‌رود خودروهای دارای سیستم عامل Android Automotive اتصال داده خودشان را داشته باشند، یعنی طرح داده در هزینه خودرو گنجانده شده باشد یا کاربر هزینه آن را پرداخت کند. بااین‌حال، انتظار می‌رود خودروها اتصال متغیرتری نسبت‌به دستگاه‌های همراه داشته باشند.

در اینجا چند نکته وجود دارد که باید هنگام بررسی استراتژی پشتیبانی آفلاین خود در نظر داشته باشید:

  • بهترین زمان برای بارگیری محتوا وقتی است که برنامه‌تان درحال استفاده است.
  • فرض نکنید که Wi-Fi دردسترس است. ممکن است خودرو هرگز در محدوده WiFi قرار نگیرد، یا OEM ممکن است WiFi را به‌نفع شبکه تلفن همراه غیرفعال کرده باشد.
  • درحالی‌که ذخیره کردن محتوایی که انتظار دارید کاربران استفاده کنند در حافظه نهان مشکلی ندارد، توصیه می‌کنیم به کاربر اجازه دهید این رفتار را ازطریق فعالیت تنظیمات شما تغییر دهد.
  • فضای دیسک در خودروها متفاوت است، بنابراین راهی برای حذف محتوای آفلاین به کاربران ارائه دهید، مثلاً ازطریق گزینه‌ای در فعالیت تنظیمات.

پشتیبانی WebView

WebView در سیستم‌عامل Android Automotive پشتیبانی می‌شود اما فقط برای فعالیت‌های ورود به سیستم و تنظیمات شما مجاز است. فعالیت‌هایی که از WebView استفاده می‌کنند باید امکان «بستن» یا «برگشتن» در خارج از WebView داشته باشند.

در اینجا چند نمونه از موارد استفاده قابل‌قبول برای WebViews آورده شده است:

  • نمایش خط‌مشی رازداری، شرایط خدمات، یا دیگر پیوندهای مرتبط با مسائل حقوقی در فعالیت تنظیمات شما.
  • جریان مبتنی بر وب در فعالیت ورود به سیستم شما.

هنگام استفاده از WebView، می‌توانید جاوا اسکریپت را فعال کنید.

ایمن‌سازی WebView

همه اقدامات احتیاطی ممکن را انجام دهید تا مطمئن شوید که «وب‌نما» شما نقطه ورودی به اینترنت بزرگ‌تر نیست. برای دیدن نمونه‌ای از نحوه قفل کردن WebView روی نشانی وب استفاده‌شده در تماس loadUrl() و جلوگیری از هدایت مجدد، تکه‌کد زیر را ببینید. توصیه می‌کنیم درصورت امکان، اقدامات حفاظتی مانند این را اجرا کنید، مثلاً هنگام نمایش پیوندهای مرتبط با مسائل حقوقی.

کاتلین

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
}

جاوا

@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 (APK) جداگانه‌ای برای سیستم‌عامل Android Automotive توزیع می‌کنید، می‌توانید از نام بسته برنامه تلفن همراهتان دوباره استفاده کنید یا نام بسته جدیدی ایجاد کنید. اگر از نام بسته دیگری استفاده کنید، برنامه‌تان دو فهرستگان «فروشگاه Play» جداگانه خواهد داشت. اگر از نام بسته فعلی‌تان مجدداً استفاده کنید، برنامه‌تان یک فهرستگان در هر دو پلاتفرم خواهد داشت.

این تصمیم عمدتاً تصمیمی تجاری است. برای مثال، اگر یک تیم دارید که روی برنامه تلفن همراه کار می‌کند و تیم دیگری دارید که روی برنامه Android Automotive OS کار می‌کند، شاید منطقی باشد که نام‌های بسته جداگانه داشته باشید و به هر تیم اجازه دهید فهرستگان «فروشگاه Play» خودش را مدیریت کند. تفاوت زیادی در تلاش فنی موردنیاز برای استفاده از هریک از این رویکردها وجود ندارد.

جدول زیر برخی‌از تفاوت‌های کلیدی دیگر بین حفظ نام بسته فعلی و استفاده از نام بسته جدید را خلاصه می‌کند:

ویژگی نام بسته یکسان نام بسته جدید
فهرست فروشگاه تکی چندگانه
نصب آینه‌ای بله: «بازنصب سریع برنامه» درطول دستیار راه‌اندازی نه
فرایند بررسی «فروشگاه Play» مسدود کردن بازبینی‌ها: اگر بازبینی برای یک APK ناموفق باشد، سایر APKهای ارسال‌شده در همان نسخه مسدود می‌شوند مرورهای فردی
آمار، سنجه‌ها، و سنجه‌های کلیدی ترکیبی: می‌توانید داده‌های خاص خودرو را فیلتر کنید. تفکیک
نمایه‌سازی و رتبه‌بندی جستجو براساس جایگاه فعلی بسازید بدون انتقال
ادغام با برنامه‌های دیگر به‌احتمال زیاد تغییری لازم نیست، با فرض اینکه کد رسانه بین هر دو APK هم‌رسانی شده است ممکن است لازم باشد برنامه مربوطه را به‌روز کنید، مثلاً برای بازپخش URI با «دستیار Google».

پرسشگان

برای دریافت پاسخ برخی‌از پرسش‌های متداول درباره «سیستم‌عامل Android Automotive»، بخش‌های زیر را ببینید.

سخت‌افزار

آیا برنامه‌ام می‌تواند به میکروفون دسترسی داشته باشد؟

برای برنامه‌هایی که Android 10 (سطح میانای برنامه‌سازی کاربردی ۲۹) یا بالاتر را هدف قرار می‌دهند، به مستندات هم‌رسانی ورودی صوتی مراجعه کنید. این کار قبل‌از سطح ای‌پی‌آی ۲۹ امکان‌پذیر نیست.

به کدام میاناهای برنامه‌سازی کاربردی خودرو می‌توانیم دسترسی داشته باشیم و چگونه؟

شما به میاناهای برنامه‌سازی کاربردی که توسط سازنده اصلی محصول ارائه شده است محدود هستید. فرایندهایی درحال توسعه است تا نحوه دسترسی شما به این میاناهای برنامه‌سازی کاربردی استاندارد شود.

برنامه‌ها می‌توانند بااستفاده از SetProperty() و GetProperty() در CarPropertyManager به میاناهای برنامه‌سازی کاربردی خودرو دسترسی پیدا کنند. برای دیدن فهرست همه ویژگی‌های دردسترس، به کد منبع یا اسناد مرجع مراجعه کنید. اگر ویژگی با @SystemApi حاشیه‌نویسی شده باشد، به برنامه‌های سیستم ازپیش بارشده محدود می‌شود.

چه نوع کدک‌های صوتی پشتیبانی می‌شوند؟

به جزئیات کدک صوتی در CDD Android مراجعه کنید.

آیا Widevine DRM پشتیبانی می‌شود؟

بله. Widevine DRM پشتیبانی می‌شود.

توسعه و آزمایش

آیا محدودیت یا توصیه‌ای برای استفاده از کیت‌های توسعه نرم‌افزار و کتابخانه‌های طرف سوم وجود دارد؟

ما هیچ دستورالعمل خاصی درباره استفاده از کیت‌های توسعه نرم‌افزار و کتابخانه‌های طرف سوم نداریم. اگر تصمیم بگیرید از کیت‌های توسعه نرم‌افزار و کتابخانه‌های طرف سوم استفاده کنید، همچنان مسئول رعایت همه الزامات کیفیت برنامه خودرو هستید.

آیا می‌توانم از سرویس پیش‌زمینه‌ای استفاده کنم؟

تنها مورد استفاده مجاز برای سرویس پیش‌زمینه‌ای، بارگیری محتوا برای استفاده آفلاین است. اگر مورد استفاده دیگری برای سرویس پیش‌زمینه‌ای دارید که می‌خواهید پشتیبانی آن را ببینید، بااستفاده از گروه بحث سیستم‌عامل Android Automotive با ما تماس بگیرید.

انتشار برنامه‌های «سیستم عامل Android Automotive»

چگونه می‌توانم برنامه «سیستم عامل Android Automotive» خود را بااستفاده از «کنسول Google Play» منتشر کنم؟

برای جزئیات بیشتر درباره نحوه انتشار برنامه سیستم عامل Android Automotive بااستفاده از «کنسول Google Play»، به توزیع در خودروها مراجعه کنید.

منابع بیشتر

برای کسب اطلاعات بیشتر درباره «سیستم عامل Android Automotive»، منابع تکمیلی زیر را ببینید.

نمونه‌ها

راهنماها

وبلاگ‌ها

ویدیوها

گزارش کردن مشکل رسانه «سیستم عامل Android Automotive»

اگر هنگام توسعه برنامه رسانه‌ای برای «سیستم‌عامل Android Automotive» با مشکلی مواجه شدید، می‌توانید آن را بااستفاده از Google Issue Tracker گزارش کنید. حتماً همه اطلاعات درخواست‌شده را در الگوی مشکل تکمیل کنید.

ایجاد مشکل جدید

قبل‌از ثبت مشکل جدید، بررسی کنید که آیا قبلاً در فهرست مشکلات گزارش شده است یا نه. می‌توانید با کلیک کردن روی ستاره مربوط به مشکل در ردیاب، مشترک شوید و به مشکلات رأی دهید. برای اطلاعات بیشتر، به مشترک شدن در مشکل مراجعه کنید.