פיתוח אפליקציית ניווט

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

הצהרה על תמיכה בניווט במניפסט

אפליקציית הניווט צריכה להצהיר על androidx.car.app.category.NAVIGATION הקטגוריה של אפליקציית הרכב במסנן ה-Intent של CarAppService:

<application>
    ...
   <service
       ...
        android:name=".MyNavigationCarAppService"
        android:exported="true">
      <intent-filter>
        <action android:name="androidx.car.app.CarAppService" />
        <category android:name="androidx.car.app.category.NAVIGATION"/>
      </intent-filter>
    </service>
    ...
</application>

תמיכה בכוונות ניווט

כדי לתמוך בכוונות ניווט באפליקציה, כולל אלה שמגיעות מ-Google Assistant באמצעות שאילתה קולית, האפליקציה צריכה לטפל בכוונה CarContext.ACTION_NAVIGATE ב-Session.onCreateScreen וב-Session.onNewIntent.

פרטים על הפורמט של הכוונה מופיעים במסמכי העזרה של CarContext.startCarApp.

גישה לתבניות הניווט

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

  • NavigationTemplate: מוצגת גם הודעה אופציונלית עם מידע משוער לגבי משך הנסיעה במהלך ניווט פעיל.
  • MapWithContentTemplate: תבנית שמאפשרת לאפליקציה ליצור ריבועי מפה עם תוכן כלשהו (לדוגמה, רשימה). בדרך כלל, התוכן מוצג כשכבת-על מעל לאריחי המפה, והאזורים היציבים והגלויים במפה משתנים בהתאם לתוכן.

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

כדי לקבל גישה לתבניות הניווט, האפליקציה צריכה להצהיר על ההרשאה androidx.car.app.NAVIGATION_TEMPLATES בקובץ AndroidManifest.xml שלה:

<manifest ...>
  ...
  <uses-permission android:name="androidx.car.app.NAVIGATION_TEMPLATES"/>
  ...
</manifest>

נדרשת הרשאה נוספת כדי לצייר מפות.

מעבר ל-MapWithContentTemplate

החל מרמת API 7 של אפליקציות לרכב, הוצאנו משימוש את הקריאות MapTemplate,‏ PlaceListNavigationTemplate ו-RoutePreviewNavigationTemplate. התמיכה בתבניות הקודמות תמשיך, אבל מומלץ מאוד לעבור ל-MapWithContentTemplate.

אפשר להטמיע את הפונקציונליות שמספקות התבניות האלה באמצעות MapWithContentTemplate. דוגמאות לקטע קוד:

MapTemplate

Kotlin

// MapTemplate (deprecated)
val template = MapTemplate.Builder()
    .setPane(paneBuilder.build())
    .setActionStrip(actionStrip)
    .setHeader(header)
    .setMapController(mapController)
    .build()

// MapWithContentTemplate
val template = MapWithContentTemplate.Builder()
    .setContentTemplate(
        PaneTemplate.Builder(paneBuilder.build())
            .setHeader(header)
            .build())
    .setActionStrip(actionStrip)
    .setMapController(mapController)
    .build()

Java

// MapTemplate (deprecated)
MapTemplate template = new MapTemplate.Builder()
    .setPane(paneBuilder.build())
    .setActionStrip(actionStrip)
    .setHeader(header)
    .setMapController(mapController)
    .build();

// MapWithContentTemplate
MapWithContentTemplate template = new MapWithContentTemplate.Builder()
    .setContentTemplate(new PaneTemplate.Builder(paneBuilder.build())
        .setHeader(header)
        build())
    .setActionStrip(actionStrip)
    .setMapController(mapController)
    .build();

PlaceListNavigationTemplate

Kotlin

// PlaceListNavigationTemplate (deprecated)
val template = PlaceListNavigationTemplate.Builder()
    .setItemList(itemListBuilder.build())
    .setHeader(header)
    .setActionStrip(actionStrip)
    .setMapActionStrip(mapActionStrip)
    .build()

// MapWithContentTemplate
val template = MapWithContentTemplate.Builder()
    .setContentTemplate(
        ListTemplate.Builder()
            .setSingleList(itemListBuilder.build())
            .setHeader(header)
            .build())
    .setActionStrip(actionStrip)
    .setMapController(
        MapController.Builder()
            .setMapActionStrip(mapActionStrip)
            .build())
    .build()

Java

// PlaceListNavigationTemplate (deprecated)
PlaceListNavigationTemplate template = new PlaceListNavigationTemplate.Builder()
    .setItemList(itemListBuilder.build())
    .setHeader(header)
    .setActionStrip(actionStrip)
    .setMapActionStrip(mapActionStrip)
    .build();

// MapWithContentTemplate
MapWithContentTemplate template = new MapWithContentTemplate.Builder()
    .setContentTemplate(new ListTemplate.Builder()
        .setSingleList(itemListBuilder.build())
        .setHeader(header)
        .build())
    .setActionStrip(actionStrip)
    .setMapController(new MapController.Builder()
        .setMapActionStrip(mapActionStrip)
        .build())
    .build();

RoutePreviewNavigationTemplate

Kotlin

// RoutePreviewNavigationTemplate (deprecated)
val template = RoutePreviewNavigationTemplate.Builder()
    .setItemList(
        ItemList.Builder()
            .addItem(
                Row.Builder()
                    .setTitle(title)
                    .build())
            .build())
    .setHeader(header)
    .setNavigateAction(
        Action.Builder()
            .setTitle(actionTitle)
            .setOnClickListener { ... }
            .build())
    .setActionStrip(actionStrip)
    .setMapActionStrip(mapActionStrip)
    .build()

// MapWithContentTemplate
val template = MapWithContentTemplate.Builder()
    .setContentTemplate(
        ListTemplate.Builder()
            .setSingleList(
                ItemList.Builder()
                    .addItem(
                        Row.Builder()
                            .setTitle(title)
                            .addAction(
                                Action.Builder()
                                    .setTitle(actionTitle)
                                    .setOnClickListener { ... }
                                    .build())
                            .build())
                    .build())
            .setHeader(header)
            .build())
    .setActionStrip(actionStrip)
    .setMapController(
        MapController.Builder()
            .setMapActionStrip(mapActionStrip)
            .build())
    .build()

Java

// RoutePreviewNavigationTemplate (deprecated)
RoutePreviewNavigationTemplate template = new RoutePreviewNavigationTemplate.Builder()
    .setItemList(new ItemList.Builder()
        .addItem(new Row.Builder()
            .setTitle(title))
            .build())
        .build())
    .setHeader(header)
    .setNavigateAction(new Action.Builder()
        .setTitle(actionTitle)
        .setOnClickListener(() -> { ... })
        .build())
    .setActionStrip(actionStrip)
    .setMapActionStrip(mapActionStrip)
    .build();

// MapWithContentTemplate
MapWithContentTemplate template = new MapWithContentTemplate.Builder()
    .setContentTemplate(new ListTemplate.Builder()
        .setSingleList(new ItemList.Builder()
            .addItem(new Row.Builder()
                  .setTitle(title))
                  .addAction(new Action.Builder()
                      .setTitle(actionTitle)
                      .setOnClickListener(() -> { ... })
                      .build())
                  .build())
            .build()))
        .setHeader(header)
        .build())
    .setActionStrip(actionStrip)
    .setMapController(new MapController.Builder()
        .setMapActionStrip(mapActionStrip)
        .build())
    .build();

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

המטא-נתונים של הניווט ניתנים דרך שירות הרכב NavigationManager, שניתן לגשת אליו דרך CarContext:

Kotlin

val navigationManager = carContext.getCarService(NavigationManager::class.java)

Java

NavigationManager navigationManager = carContext.getCarService(NavigationManager.class);

הפעלה, סיום ועצירה של הניווט

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

צריך להפעיל את NavigationManager.navigationEnded רק כשהמשתמש מסיים לנווט. לדוגמה, אם צריך לחשב מחדש את המסלול באמצע הנסיעה, משתמשים במקום זאת ב-Trip.Builder.setLoading(true).

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

עדכון פרטי הנסיעה

במהלך ניווט פעיל, מקישים על NavigationManager.updateTrip. המידע שסופק בקריאה הזו יכול לשמש את קבוצת המחוונים ואת התצוגה העילית של הרכב. בהתאם לרכב הספציפי שבו נוהגים, לא כל המידע מוצג למשתמש. לדוגמה, ב-Desktop Head Unit (DHU) מוצג הערך Step שנוסף ל-Trip, אבל לא מוצג המידע של Destination.

ציור בלוח המחוונים האשכולי

כדי לספק את חוויית המשתמש הכי מרתקת, כדאי להציג יותר ממטא-נתונים בסיסיים בלוח המחוונים של הרכב. החל מרמה 6 של Car App API, לאפליקציות ניווט יש אפשרות להציג את התוכן שלהן ישירות במסך האשכולות (ברכבים נתמכים), עם המגבלות הבאות:

  • ממשק ה-API של תצוגת האשכולות לא תומך באמצעי בקרה על קלט
  • הנחיה בנושא איכות של אפליקציות לכלי רכב NF-9: בתצוגת האשכולות צריכים להופיע רק אריחי מפה. אפשר גם להציג את מסלול הניווט הפעיל באריחים האלה.
  • ב-Cluster Display API יש תמיכה רק בשימוש ב-NavigationTemplate
    • בניגוד למסכים הראשיים, יכול להיות שבמסכי האשכולות לא יוצגו באופן עקבי כל אלמנטים של ממשק המשתמש של NavigationTemplate, כמו הוראות מפורטות, כרטיסי זמן הגעה משוער ופעולות. המשבצות של המפה הן הרכיב היחיד בממשק המשתמש שמוצג באופן עקבי.

הצהרת תמיכה באשכולות

כדי להודיע לאפליקציית המארח שהאפליקציה תומכת ברינדור במסכים של האשכולות, צריך להוסיף את האלמנט androidx.car.app.category.FEATURE_CLUSTER <category> ל-<intent-filter> של CarAppService, כפי שמוצג בקטע הקוד הבא:

<application>
    ...
   <service
       ...
        android:name=".MyNavigationCarAppService"
        android:exported="true">
      <intent-filter>
        <action android:name="androidx.car.app.CarAppService" />
        <category android:name="androidx.car.app.category.NAVIGATION"/>
        <category android:name="androidx.car.app.category.FEATURE_CLUSTER"/>
      </intent-filter>
    </service>
    ...
</application>

ניהול מחזור חיים ומצבים

החל מרמה 6 של ה-API, תהליך מחזור החיים של אפליקציית הרכב נשאר ללא שינוי, אבל עכשיו CarAppService::onCreateSession מקבל פרמטר מסוג SessionInfo שמספק מידע נוסף על Session שנוצר (כלומר, סוג התצוגה וקבוצת התבניות הנתמכות).

לאפליקציות יש אפשרות להשתמש באותה כיתה Session כדי לטפל גם באשכול וגם במסך הראשי, או ליצור Sessions ספציפי למסך כדי להתאים אישית את ההתנהגות בכל מסך (כפי שמוצג בקטע הקוד הבא).

Kotlin

override fun onCreateSession(sessionInfo: SessionInfo): Session {
  return if (sessionInfo.displayType == SessionInfo.DISPLAY_TYPE_CLUSTER) {
    ClusterSession()
  } else {
    MainDisplaySession()
  }
}

Java

@Override
@NonNull
public Session onCreateSession(@NonNull SessionInfo sessionInfo) {
  if (sessionInfo.getDisplayType() == SessionInfo.DISPLAY_TYPE_CLUSTER) {
    return new ClusterSession();
  } else {
    return new MainDisplaySession();
  }
}

אין ערובה לגבי המועד שבו תצוגת האשכולות תסופק, או אם היא תסופק בכלל. ייתכן גם ש-Session של האשכולות יהיה ה-Session היחיד (לדוגמה, המשתמש החליף את המסך הראשי לאפליקציה אחרת בזמן שהאפליקציה שלכם מבצעת ניווט פעיל). ההסכם 'הסטנדרטי' הוא שהאפליקציה מקבלת שליטה על תצוגת האשכולות רק אחרי שמפעילים את NavigationManager::navigationStarted. עם זאת, יכול להיות שהאפליקציה תקבל את תצוגת האשכול גם אם אין ניווט פעיל, או שהיא לא תקבל אותה אף פעם. האפליקציה שלכם צריכה לטפל בתרחישים האלה על ידי עיבוד של מצב ההשבתה של האפליקציה של משבצות המפה.

המארח יוצר מכונות binder ו-CarContext נפרדות לכל Session. כלומר, כשמשתמשים בשיטות כמו ScreenManager::push או Screen::invalidate, רק ה-Session שממנו הן נקראות מושפע. אם יש צורך בתקשורת בין מכונות Session, האפליקציות צריכות ליצור ערוצי תקשורת משלהם בין המכונות האלה (לדוגמה, באמצעות שידורים, אובייקט singleton משותף או דרך אחרת).

בדיקת התמיכה באשכולות

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

התאמה אישית של 'הערכת זמן הנסיעה' באמצעות טקסט או סמל

כדי להתאים אישית את הערכת הזמן של המסלול באמצעות טקסט, סמל או שניהם, משתמשים ב-methods‏ setTripIcon או setTripText של הכיתה TravelEstimate.Builder. ב-NavigationTemplate אפשר להשתמש ב-TravelEstimate כדי להציג טקסט וסמלים לצד זמן ההגעה המשוער, הזמן שנותר והמרחק שנותר, או במקומם.

איור 1. אומדן נסיעה עם סמל וטקסט בהתאמה אישית.

בקטע הקוד הבא נעשה שימוש ב-setTripIcon וב-setTripText כדי להתאים אישית את האומדן של זמן הנסיעה:

Kotlin

TravelEstimate.Builder(Distance.create(...), DateTimeWithZone.create(...))
      ...
      .setTripIcon(CarIcon.Builder(...).build())
      .setTripText(CarText.create(...))
      .build()

Java

new TravelEstimate.Builder(Distance.create(...), DateTimeWithZone.create(...))
      ...
      .setTripIcon(CarIcon.Builder(...).build())
      .setTripText(CarText.create(...))
      .build();

לקבל התראות על מסלול מפורט

לספק הוראות ניווט מפורטות (TBT) באמצעות התראה על ניווט שמתעדכנת לעיתים קרובות. כדי שההתראה תטופל כהתראה על ניווט במסך הרכב, ה-builder של ההתראה צריך לבצע את הפעולות הבאות:

  1. מסמנים את ההתראה כמתמשכת באמצעות השיטה NotificationCompat.Builder.setOngoing.
  2. מגדירים את הקטגוריה של ההתראה כ-Notification.CATEGORY_NAVIGATION.
  3. כדי להרחיב את ההתראה, מקישים על CarAppExtender.

התראה על ניווט תוצג בווידג'ט של המסילה בתחתית המסך ברכב. אם רמת החשיבות של ההתראה מוגדרת כ-IMPORTANCE_HIGH, היא תוצג גם כהודעה מראש (HUN). אם לא מגדירים את מידת החשיבות באמצעות השיטה CarAppExtender.Builder.setImportance, המערכת משתמשת במידת החשיבות של ערוץ ההתראות.

האפליקציה יכולה להגדיר PendingIntent ב-CarAppExtender שנשלח לאפליקציה כשהמשתמש מקשיב על HUN או על הווידג'ט של המסילה.

אם NotificationCompat.Builder.setOnlyAlertOnce נקרא עם הערך true, התראה ברמת חשיבות גבוהה תופיע רק פעם אחת ב-HUN.

בקטע הקוד הבא מוסבר איך ליצור התראה על ניווט:

Kotlin

NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
    ...
    .setOnlyAlertOnce(true)
    .setOngoing(true)
    .setCategory(NotificationCompat.CATEGORY_NAVIGATION)
    .extend(
        CarAppExtender.Builder()
            .setContentTitle(carScreenTitle)
            ...
            .setContentIntent(
                PendingIntent.getBroadcast(
                    context,
                    ACTION_OPEN_APP.hashCode(),
                    Intent(ACTION_OPEN_APP).setComponent(
                        ComponentName(context, MyNotificationReceiver::class.java)),
                        0))
            .setImportance(NotificationManagerCompat.IMPORTANCE_HIGH)
            .build())
    .build()

Java

new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
    ...
    .setOnlyAlertOnce(true)
    .setOngoing(true)
    .setCategory(NotificationCompat.CATEGORY_NAVIGATION)
    .extend(
        new CarAppExtender.Builder()
            .setContentTitle(carScreenTitle)
            ...
            .setContentIntent(
                PendingIntent.getBroadcast(
                    context,
                    ACTION_OPEN_APP.hashCode(),
                    new Intent(ACTION_OPEN_APP).setComponent(
                        new ComponentName(context, MyNotificationReceiver.class)),
                        0))
            .setImportance(NotificationManagerCompat.IMPORTANCE_HIGH)
            .build())
    .build();

כדאי לעדכן את ההתראה על זמן הגעה משוער באופן קבוע כדי לשקף שינויים במרחק, וכך לעדכן את הווידג'ט של הרכבת. בנוסף, כדאי להציג את ההתראה רק כ-HUN. כדי לקבוע את התנהגות ה-HUN, אפשר להגדיר את רמת החשיבות של ההתראה באמצעות CarAppExtender.Builder.setImportance. אם מגדירים את רמת החשיבות ל-IMPORTANCE_HIGH, מוצגת הודעה על HUN. הגדרה של ערך אחר מעדכנת רק את הווידג'ט של המסילה.

רענון התוכן של PlaceListNavigationTemplate

אתם יכולים לאפשר לנהגים לרענן את התוכן בלחיצה על לחצן בזמן שהם גולשים ברשימות של מקומות שנוצרו באמצעות PlaceListNavigationTemplate. כדי להפעיל את הרענון של הרשימה, מטמיעים את השיטה onContentRefreshRequested של הממשק OnContentRefreshListener ומשתמשים ב-PlaceListNavigationTemplate.Builder.setOnContentRefreshListener כדי להגדיר את המאזין בתבנית.

בקטע הקוד הבא מוצג איך להגדיר את המאזין בתבנית:

Kotlin

PlaceListNavigationTemplate.Builder()
    ...
    .setOnContentRefreshListener {
        // Execute any desired logic
        ...
        // Then call invalidate() so onGetTemplate() is called again
        invalidate()
    }
    .build()

Java

new PlaceListNavigationTemplate.Builder()
        ...
        .setOnContentRefreshListener(() -> {
            // Execute any desired logic
            ...
            // Then call invalidate() so onGetTemplate() is called again
            invalidate();
        })
        .build();

לחצן הרענון מופיע בכותרת של PlaceListNavigationTemplate רק אם למאזין יש ערך.

כשהמשתמש לוחץ על לחצן הרענון, מתבצעת קריאה ל-method‏ onContentRefreshRequested של ההטמעה של OnContentRefreshListener. ב-onContentRefreshRequested, קוראים ל-method‏ Screen.invalidate. לאחר מכן, המארח קורא שוב לשיטה Screen.onGetTemplate של האפליקציה כדי לאחזר את התבנית עם התוכן המעודכן. מידע נוסף על רענון תבניות זמין במאמר רענון התוכן של תבנית. כל עוד התבנית הבאה שתוחזר על ידי onGetTemplate היא מאותו סוג, היא נחשבת לרענון ולא נספרת במכסת התבניות.

לספק הנחיות קוליות

כדי להפעיל הוראות ניווט דרך הרמקולים של הרכב, האפליקציה צריכה לבקש מיקוד אודיו. כחלק מAudioFocusRequest, מגדירים את השימוש כ-AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE. כמו כן, מגדירים את התגובה של הפוקוס כ-AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK.

סימולציה של ניווט

כדי לאמת את פונקציונליות הניווט של האפליקציה כששולחים אותה לחנות Google Play, צריך להטמיע באפליקציה את פונקציית ה-callback‏ NavigationManagerCallback.onAutoDriveEnabled. כשהקריאה החוזרת הזו מתבצעת, האפליקציה צריכה לדמות ניווט ליעד שנבחר כשהמשתמש מתחיל לנווט. האפליקציה יכולה לצאת מהמצב הזה בכל שלב שבו מחזור החיים של Session הנוכחי מגיע למצב Lifecycle.Event.ON_DESTROY.

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

adb shell dumpsys activity service CAR_APP_SERVICE_NAME AUTO_DRIVE

הדוגמה הבאה ממחישה זאת:

adb shell dumpsys activity service androidx.car.app.samples.navigation.car.NavigationCarAppService AUTO_DRIVE

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

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

הצגת התראות ניווט בהקשר

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

Alert זמין רק ב-NavigationTemplate. כדי להודיע למשתמש מחוץ ל-NavigationTemplate, מומלץ להשתמש בהתראה מראש (HUN), כפי שמוסבר בקטע הצגת התראות.

לדוגמה, אפשר להשתמש ב-Alert כדי:

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

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

איור 2. התראה על ניווט בהקשר.

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

יצירת התראה

משתמשים ב-Alert.Builder כדי ליצור מכונה של Alert:

Kotlin

Alert.Builder(
        /*alertId*/ 1,
        /*title*/ CarText.create("Hello"),
        /*durationMillis*/ 5000
    )
    // The fields below are optional
    .addAction(firstAction)
    .addAction(secondAction)
    .setSubtitle(CarText.create(...))
    .setIcon(CarIcon.APP_ICON)
    .setCallback(...)
    .build()

Java

new Alert.Builder(
        /*alertId*/ 1,
        /*title*/ CarText.create("Hello"),
        /*durationMillis*/ 5000
    )
    // The fields below are optional
    .addAction(firstAction)
    .addAction(secondAction)
    .setSubtitle(CarText.create(...))
    .setIcon(CarIcon.APP_ICON)
    .setCallback(...)
    .build();

אם רוצים להאזין לביטול או לסגירה של Alert, צריך ליצור הטמעה של הממשק AlertCallback. נתיבי הקריאה של AlertCallback הם:

הגדרת משך ההתראה

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

הצגת התראה

כדי להציג Alert, צריך להפעיל את השיטה AppManager.showAlert שזמינה דרך CarContext של האפליקציה.

// Show an alert
carContext.getCarService(AppManager.class).showAlert(alert)
  • קריאה ל-showAlert עם Alert שיש לו alertId זהה למזהה של Alert שמוצג כרגע לא גורמת לשום דבר. הערך של Alert לא מתעדכן. כדי לעדכן Alert, צריך ליצור אותו מחדש באמצעות alertId חדש.
  • קריאה ל-showAlert עם Alert שיש לו alertId שונה מ-Alert שמוצג כרגע תסגור את Alert שמוצג כרגע.

סגירת התראה

Alert נסגר באופן אוטומטי עקב זמן קצוב לתפוגה או אינטראקציה של הנהג, אבל אפשר גם לסגור Alert באופן ידני, למשל אם המידע שלו לא עדכני. כדי לסגור Alert, צריך לבצע קריאה ל-method‏ dismissAlert עם alertId של ה-Alert.

// Dismiss the same alert
carContext.getCarService(AppManager.class).dismissAlert(alert.getId())

קריאה לפונקציה dismissAlert עם alertId שלא תואם ל-Alert שמוצג כרגע לא גורמת לשום דבר. היא לא מפעילה חריגה.