הוספת תמיכה ב-Android Automotive OS לאפליקציית המדיה

מערכת ההפעלה Android Automotive OS מאפשרת למשתמשים להתקין אפליקציות ברכב. כדי להגיע למשתמשים בפלטפורמה הזו, צריך להפיץ אפליקציה מותאמת לנהגים שתואמת ל-Android Automotive OS. אפשר להשתמש כמעט בכל הקוד והמשאבים מאפליקציית Android Auto, אבל צריך ליצור גרסת build נפרדת שעומדת בדרישות שמפורטות בדף הזה.

סקירה כללית על הפיתוח

כדי להוסיף תמיכה ב-Android Automotive OS, צריך לבצע רק כמה שלבים, כפי שמתואר בקטעים הבאים:

  1. הפעלת תכונות לכלי רכב ב-Android Studio.
  2. יוצרים מודול לכלי רכב.
  3. עדכון יחסי התלות ב-Gradle
  4. לחלופין, מטמיעים הגדרות ופעילויות כניסה.
  5. לחלופין, קוראים את הטיפים למארחי מדיה.

שיקולים לגבי עיצוב

מערכת Android Automotive OS אחראית על פריסת תוכן המדיה שהיא מקבלת משירות דפדפן המדיה של האפליקציה. המשמעות היא שהאפליקציה לא תיצור את ממשק המשתמש ולא תפעיל אף אחת מהפעילויות שלכם כשמשתמש יפעיל את הפעלת המדיה.

אם אתם מטמיעים הגדרות או פעילויות כניסה, הפעילויות האלה צריכות להיות מותאמות לרכב. כשאתם מתכננים את האזורים האלה באפליקציה, כדאי לעיין בהנחיות לעיצוב של Android Automotive OS.

הגדרת הפרויקט

כדי להפעיל תמיכה ב-Android Automotive OS, צריך להגדיר כמה חלקים בפרויקט של האפליקציה.

הפעלת תכונות לכלי רכב ב-Android Studio

כדי לוודא שכל התכונות של Automotive OS מופעלות, צריך להשתמש ב-Android Studio בגרסה 4.0 ואילך.

יצירת מודול לכלי רכב

לחלק מהרכיבים של Android Automotive OS, כמו המניפסט, יש דרישות ספציפיות לפלטפורמה. יוצרים מודול שיכול להפריד את הקוד של הרכיבים האלה מהקוד האחר בפרויקט, כמו הקוד שמשמש את אפליקציית הטלפון.

כדי להוסיף מודול לכלי רכב לפרויקט:

  1. ב-Android Studio, לוחצים על קובץ > חדש > מודול חדש.
  2. בוחרים באפשרות Automotive Module ולוחצים על Next.
  3. מזינים שם של אפליקציה/ספרייה. זה השם שיוצג למשתמשים באפליקציה שלכם ב-Android Automotive OS.
  4. מזינים שם למערך.
  5. משנים את שם החבילה כך שיתאים לאפליקציה.
  6. בוחרים באפשרות API 28: Android 9.0 (Pie) עבור גרסת ה-SDK המינימלית, ואז לוחצים על הבא.

    כל המכוניות שתומכות ב-Android Automotive OS פועלות ב-Android 9 (רמת API 28) ואילך, ולכן בחירת הערך הזה תגדיר את הטירגוט לכל המכוניות התואמות.

  7. בוחרים באפשרות No Activity (אין פעילות) ולוחצים על Finish (סיום).

אחרי שיוצרים את המודול ב-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 OS. שימו לב שאין פעילויות שמוצהרות במניפסט.

אם מטמיעים הגדרות או פעילויות כניסה, מוסיפים אותן כאן. המערכת מפעילה את הפעילויות האלה באמצעות כוונות מפורשות, והן הפעילויות היחידות שאתם מגדירים במניפסט של האפליקציה ל-Android Automotive OS.

אחרי שמוסיפים הגדרות או פעילויות כניסה, משלימים את קובץ המניפסט על ידי הגדרת המאפיין 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 OS.

הצהרה על תמיכה במדיה ב-Android Automotive OS

כדי להצהיר שהאפליקציה תומכת ב-Android Automotive OS, משתמשים ברשומה הבאה במניפסט:

<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 OS משתמשת ב-Intent מפורשים כדי להפעיל פעילויות באפליקציית המדיה. אין לכלול בקובץ המניפסט פעילויות עם מסנני Intent מסוג CATEGORY_LAUNCHER או ACTION_MAIN.

פעילויות כמו זו שבדוגמה הבאה בדרך כלל מטרגטות טלפון או מכשיר נייד אחר. צריך להצהיר על הפעילויות האלה במודול שמפתח את אפליקציית הטלפון, ולא במודול שמפתח את האפליקציה ל-Android Automotive OS.

<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

Groovy

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

Kotlin

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

הטמעת הגדרות ופעילויות כניסה

בנוסף לשירות דפדפן המדיה, אפשר גם לספק הגדרות שמותאמות לרכב ופעילויות כניסה לאפליקציה של Android Automotive OS. הפעילויות האלה מאפשרות לספק פונקציונליות של האפליקציה שלא כלולה ב-Android Media APIs.

כדאי להטמיע את הפעילויות האלה רק אם האפליקציה שלכם ל-Android Automotive OS צריכה לאפשר למשתמשים להיכנס לחשבון או לציין את הגדרות האפליקציה. מערכת Android Auto לא משתמשת בפעילויות האלה.

תהליכי עבודה של פעילויות

התרשים הבא מציג את האינטראקציה של המשתמש עם ההגדרות ועם פעילויות הכניסה באמצעות מערכת ההפעלה Android Automotive OS:

תהליכי עבודה לפעילויות של הגדרות וכניסה

איור 1. תהליכי עבודה של הגדרות ופעילויות כניסה.

להימנע מהסחות דעת בהגדרות ובפעילויות הכניסה

כדי לוודא שההגדרות ו/או פעילויות הכניסה לחשבון יהיו זמינות לשימוש רק כשהרכב של המשתמש חונה, צריך לוודא שהרכיבים של <activity> לא כוללים את הרכיב הבא של <meta-data>. אם יימצא רכיב כזה, האפליקציה תידחה במהלך הבדיקה.

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

הוספת פעילות של הגדרות

אתם יכולים להוסיף פעילות של הגדרות שמותאמות לרכב כדי שהמשתמשים יוכלו להגדיר את ההגדרות של האפליקציה ברכב. הפעילות בחשבון יכולה לספק תהליכי עבודה אחרים, כמו כניסה לחשבון של משתמש או יציאה ממנו, או מעבר בין חשבונות משתמשים. חשוב לזכור שהפעילות הזו מופעלת רק על ידי אפליקציה שפועלת ב-Android Automotive OS. אפליקציות בטלפון שמחוברות ל-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 OS מזהה את פעילות ההגדרות שהצהרתם עליה ומציגה רכיב עזר, כמו סמל. המשתמש יכול להקיש על האפשרות הזו או לבחור בה במסך הרכב כדי לנווט לפעילות. מערכת Android Automotive OS שולחת את הכוונה 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
      • אפשר להתאים אישית את הלוגיקה בקריאה החוזרת (callback) של 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 OS. אפליקציות בטלפון שמחוברות ל-Android Auto לא משתמשות בו.

דרישה לכניסה לחשבון בזמן הפעלת האפליקציה

כדי לחייב משתמשים להיכנס לחשבון לפני שהם יכולים להשתמש באפליקציה, שירות דפדפן המדיה צריך לבצע את הפעולות הבאות:

  1. בשיטה onLoadChildren() של השירות, שולחים את התוצאה null באמצעות השיטה sendResult().
  2. מגדירים את PlaybackStateCompat של סשן המדיה ל-STATE_ERROR באמצעות השיטה setState(). הפקודה הזו מורה ל-Android Automotive OS שלא ניתן לבצע פעולות אחרות עד לפתרון השגיאה.
  3. מגדירים את קוד השגיאה PlaybackStateCompat של סשן המדיה לערך ERROR_CODE_AUTHENTICATION_EXPIRED. כך מערכת Android Automotive OS תדע שהמשתמש צריך לבצע אימות.
  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 OS על ידי קריאה לשיטה finish() של הפעילות.

הטמעת הפעילות של כניסה לחשבון

Google מציעה מגוון כלים לזיהוי שיעזרו למשתמשים להיכנס לאפליקציה שלכם ברכב. כלים מסוימים, כמו אימות ב-Firebase, מספקים ערכות כלים מלאות שיכולות לעזור לכם ליצור חוויות אימות בהתאמה אישית. כלים אחרים משתמשים בפרטי הכניסה הקיימים של המשתמש או בטכנולוגיות אחרות כדי לעזור לכם ליצור חוויית כניסה חלקה למשתמשים.

בעזרת הכלים הבאים תוכלו ליצור חוויית כניסה קלה יותר למשתמשים שכבר נכנסו בעבר במכשיר אחר:

  • כניסה ורשמה בנגיעה אחת: אם כבר הטמעתם את התכונה 'נגיעה אחת' במכשירים אחרים, כמו אפליקציית הטלפון, תוכלו להטמיע אותה באפליקציה של Android Automotive OS כדי לתמוך במשתמשים קיימים ב'נגיעה אחת'.
  • כניסה באמצעות חשבון Google: אם כבר הטמעתם את הכניסה באמצעות חשבון Google במכשירים אחרים, כמו אפליקציית הטלפון, תוכלו להטמיע את הכניסה באמצעות חשבון Google באפליקציה של Android Automotive OS כדי לתמוך במשתמשים קיימים בכניסה באמצעות חשבון Google.
  • מילוי אוטומטי של Google: אם המשתמשים הביעו הסכמה לשימוש במילוי האוטומטי של Google במכשירי Android אחרים שלהם, פרטי הכניסה שלהם נשמרים במנהל הסיסמאות של Google. כשהמשתמשים האלה נכנסים לאפליקציה שלכם ל-Android Automotive OS, המילוי האוטומטי של Google מציע פרטי כניסה רלוונטיים ששמורים. כדי להשתמש במילוי אוטומטי של Google, לא צריך לפתח אפליקציה. עם זאת, מפתחי אפליקציות יכולים לבצע אופטימיזציה של האפליקציות שלהם כדי לשפר את איכות התוצאות. התכונה 'מילוי אוטומטי באמצעות Google' נתמכת בכל המכשירים עם Android מגרסה 8.0 (רמת API‏ 26) ואילך, כולל Android Automotive OS.

שימוש ב-AccountManager

אפליקציות ל-Android Automotive OS עם אימות חייבות להשתמש ב-AccountManager, מהסיבות הבאות:

  • חוויית משתמש משופרת וניהול קל יותר של החשבונות: המשתמשים יכולים לנהל בקלות את כל החשבונות שלהם מתפריט החשבונות בהגדרות המערכת, כולל כניסה לחשבון ויציאה ממנו.
  • חוויות 'אורח': מכוניות הן מכשירים משותפים, כך שיצרני ציוד מקורי יכולים להפעיל חוויות 'אורח' ברכב, שבהן אי אפשר להוסיף חשבונות. ההגבלה הזו מתבצעת באמצעות DISALLOW_MODIFY_ACCOUNTS עבור AccountManager.

הרשאות

אם אתם צריכים לבקש הרשאות מהמשתמש, השתמשו באותו תהליך כמו בפעילות האימות או בפעילות ההגדרות בתרשים של תהליכי העבודה של הפעילויות שמוצג בקטע הקודם.

קריאה של טיפים למארחי מדיה

בהתאם לאפליקציית המערכת (כולל הגרסה שלה) שמתחברת לשירות דפדפן המדיה, האפליקציה עשויה לקבל את התוספים הבאים:

טיפול בשגיאות

שגיאות באפליקציות מדיה ב-Android Automotive OS מועברות דרך PlaybackStateCompat של סשן המדיה. לכל השגיאות, מגדירים קוד שגיאה והודעת שגיאה מתאימים ב-PlaybackStateCompat. כתוצאה מכך, הערך Toast יופיע בממשק המשתמש.

כשמתרחשת שגיאה אבל ההפעלה יכולה להמשיך, יש להנפיק שגיאה לא קטלנית. לדוגמה, יכול להיות שמשתמש יוכל להפעיל מוזיקה באפליקציה לפני הכניסה לחשבון, אבל הוא יצטרך להיכנס לחשבון כדי לדלג על שיר. כשמשתמשים בשגיאה לא קטלנית, המערכת יכולה להציע למשתמש להיכנס לחשבון בלי להפריע להפעלה של פריט המדיה הנוכחי.

כשמתקבלת שגיאה לא קריטית, שומרים את שאר הנתונים ב-PlaybackStateCompat כפי שהם, מלבד קוד השגיאה והודעת השגיאה. הגישה הזו מאפשרת להמשיך את ההפעלה של פריט המדיה הנוכחי בזמן שהמשתמש מחליט אם להיכנס לחשבון.

כשאי אפשר להפעיל את התוכן, למשל אם אין חיבור לאינטרנט ואין תוכן אופליין, מגדירים את המצב PlaybackStateCompat ל-STATE_ERROR.

בעדכונים הבאים של PlaybackStateCompat, צריך למחוק את כל קודי השגיאה והודעות השגיאה כדי למנוע הצגה של כמה אזהרות לגבי אותה שגיאה.

אם בשלב כלשהו לא ניתן לטעון עץ ניווט – לדוגמה, אם נדרש אימות והמשתמש לא נכנס לחשבון – שולחים עץ ניווט ריק. כדי לציין זאת, צריך להחזיר תוצאה null מ-onLoadChildren() עבור צומת המדיה ברמה הבסיסית. במקרה כזה, המערכת תציג הודעת שגיאה במסך מלא עם הודעת השגיאה שמוגדרת ב-PlaybackStateCompat.

שגיאות שניתן לפעול לפיהן

אם אפשר לפעול לפי השגיאה, צריך להגדיר גם את שני הפריטים הנוספים הבאים ב-PlaybackStateCompat:

שגיאות שניתן לטפל בהן מופיעות כסמל Dialog, והמשתמשים יכולים לפתור אותן רק כשהרכב נעצר.

בדיקת מקרים של שגיאות

מוודאים שהאפליקציה מטפלת בשגיאות בצורה תקינה בכל התרחישים, כולל:

  • רמות שונות של המוצר: לדוגמה, חינמי לעומת פרימיום או כניסה לעומת יציאה
  • מצבי נסיעה שונים: לדוגמה, 'חניה' לעומת 'נהיגה'
  • מצבי קישוריות שונים: לדוגמה, אופליין או אונליין

שיקולים נוספים

כדאי להביא בחשבון את השיקולים הבאים כשאתם מפתחים אפליקציה ל-Android Automotive OS:

תוכן אופליין

אם רלוונטי, מטמיעים תמיכה בהפעלה במצב אופליין. רכבים עם Android Automotive OS צפויים לכלול קישוריות נתונים משלהם, כלומר חבילת גלישה כלולה בעלות הרכב או שהמשתמש משלם עליה. עם זאת, צפויה גם קישוריות משתנה יותר ברכב מאשר במכשירים ניידים.

ריכזנו כאן כמה דברים שכדאי לזכור כשאתם בוחרים את אסטרטגיית התמיכה אופליין:

  • הזמן הטוב ביותר להורדת תוכן הוא בזמן השימוש באפליקציה.
  • אל תניחו שה-Wi-Fi זמין. יכול להיות שמעולם לא תהיה אפשרות להתחבר לרשת Wi-Fi ברכב, או שהיצרן המקורי השבית את ה-Wi-Fi לטובת רשת סלולרית.
  • מותר לשמור בזיכרון מטמון בצורה חכמה את התוכן שהמשתמשים צפויים להשתמש בו, אבל מומלץ לאפשר למשתמשים לשנות את ההתנהגות הזו דרך פעילות ההגדרות.
  • נפח האחסון בכונן משתנה בין רכבים, לכן כדאי לתת למשתמשים אפשרות למחוק תוכן אופליין, למשל באמצעות אפשרות בהגדרות.

תמיכה ב-WebView

רכיבי WebView נתמכים ב-Android Automotive OS, אבל מותר להשתמש בהם רק לצורך הגדרות ופעילויות כניסה. בפעילויות שמשתמשות ב-WebView חייבת להיות אפשרות 'סגירה' או 'חזרה' מחוץ ל-WebView.

ריכזנו כאן כמה דוגמאות לתרחישים לדוגמה שמותר להשתמש בהם ב-WebViews:

  • הצגת מדיניות הפרטיות, התנאים וההגבלות או קישורים משפטיים אחרים בפעילות ההגדרות.
  • תהליך מבוסס-אינטרנט בפעילות הכניסה שלכם.

כשמשתמשים ב-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 נפרדת (APK) ל-Android Automotive OS, תוכלו לעשות שימוש חוזר בשם החבילה מהאפליקציה לנייד או ליצור שם חבילה חדש. אם משתמשים בשם חבילה שונה, לאפליקציה יהיו שני כרטיסי מוצר נפרדים ב-Play Store. אם משתמשים שוב בשם החבילה הנוכחי, לאפליקציה תהיה כרטיס אחד בשתי הפלטפורמות.

זו בעיקר החלטה עסקית. לדוגמה, אם יש לכם צוות אחד שעובד על האפליקציה לנייד וצוות נפרד שעובד על האפליקציה ל-Android Automotive OS, יכול להיות שיהיה הגיוני להשתמש בשמות חבילה נפרדים ולאפשר לכל צוות לנהל את דף האפליקציה שלו בחנות Play. אין הבדל גדול במאמץ הטכני הנדרש לשימוש בכל אחת מהגישות.

בטבלה הבאה מפורטים כמה הבדלים עיקריים נוספים בין שמירת שם החבילה הנוכחי לבין שימוש בשם חבילה חדש:

תכונה שם חבילה זהה שם החבילה החדש
רישום חנות יחיד יותר מאחת
התקנה במראה כן: 'התקנה מהירה מחדש של האפליקציה' במהלך האשף להגדרה לא
תהליך הבדיקה של חנות Play בדיקות חסימה: אם הבדיקה נכשלת לגבי קובץ APK אחד, קובצי APK אחרים שנשלחו באותה גרסה ייחסמו ביקורות ספציפיות
נתונים סטטיסטיים, מדדים ומדדי ביצועים בשילוב: אפשר לסנן לפי נתונים ספציפיים לכלי רכב. כן, אני רוצה להפריד
הוספה לאינדקס ודירוג בחיפוש התבססות על המצב הנוכחי ללא העברה
שילוב עם אפליקציות אחרות סביר להניח שאין צורך בשינויים, בהנחה שקוד המדיה משותף בין שני קובצי ה-APK יכול להיות שתצטרכו לעדכן את האפליקציה המתאימה, למשל כדי להפעיל URI באמצעות Google Assistant.

שאלות נפוצות

בקטעים הבאים מפורטות תשובות לכמה מהשאלות הנפוצות ביותר בנושא Android Automotive OS.

חומרה

האם לאפליקציה שלי יש גישה למיקרופון

באפליקציות שמטרגטות ל-Android 10 ואילך (רמת API ‏29 ואילך), יש לעיין במסמכי התיעוד בנושא שיתוף הקלט של אודיו. אי אפשר לעשות זאת לפני רמת API‏ 29.

לאילו ממשקי API של רכב יש לנו גישה ואיך?

אתם מוגבלים לממשקי ה-API שנחשפים על ידי יצרן הציוד המקורי. אנחנו מפתחים תהליכים כדי לסטנדרטיזציה של הגישה לממשקי ה-API האלה.

אפליקציות יכולות לגשת לממשקי API של רכב באמצעות SetProperty() ו-GetProperty() ב-CarPropertyManager. רשימה של כל המאפיינים הזמינים מופיעה בקוד המקור או במסמכי העזרה. אם המאפיין סומן ב-@SystemApi, הוא מוגבל לאפליקציות מערכת שהוטענו מראש.

אילו סוגי קודיקים של אודיו נתמכים?

אפשר לעיין בפרטי הקודק של האודיו במסמך Android CDD.

האם יש תמיכה ב-Widevine DRM?

כן. יש תמיכה ב-Widevine DRM.

פיתוח ובדיקה

האם יש הגבלות או המלצות לשימוש בספריות ובערכות SDK של צד שלישי?

אין לנו הנחיות ספציפיות לשימוש בספריות וב-SDK של צד שלישי. אם בחרתם להשתמש בספריות וב-SDK של צד שלישי, עדיין באחריותכם לעמוד בכל דרישות האיכות של אפליקציות לרכב.

האם אפשר להשתמש בשירות שפועל בחזית?

התרחיש היחיד שבו מותר להשתמש בשירות שפועל בחזית הוא הורדת תוכן לשימוש אופליין. אם יש לכם תרחיש לדוגמה נוסף לשירות בחזית שאתם רוצים שנוסיף תמיכה בו, תוכלו ליצור איתנו קשר דרך קבוצת הדיון של Android Automotive OS.

פרסום אפליקציות ל-Android Automotive OS

איך מפרסמים אפליקציה ל-Android Automotive OS באמצעות Google Play Console?

במאמר הפצה למכוניות מוסבר איך מפרסמים אפליקציות ל-Android Automotive OS באמצעות Google Play Console.

מקורות מידע נוספים

מידע נוסף על Android Automotive OS זמין במשאבים הבאים.

דוגמיות

מדריכים

בלוגים

סרטונים

דיווח על בעיה במדיה ב-Android Automotive OS

אם נתקלתם בבעיה במהלך הפיתוח של אפליקציית המדיה ל-Android Automotive OS, תוכלו לדווח עליה באמצעות Google Issue Tracker. חשוב למלא את כל המידע הנדרש בתבנית הדיווח על הבעיה.

דיווח על בעיה חדשה

לפני שמדווחים על בעיה חדשה, כדאי לבדוק אם היא כבר דווחה ברשימת הבעיות. כדי להירשם לבעיות ולהצביע עליהן, לוחצים על הכוכב של הבעיה במעקב. מידע נוסף זמין במאמר הרשמה לבעיה.