ナビゲーション アプリを作成する

このページでは、ターンバイターン方式のナビゲーション アプリの機能を実装するために使用できる、自動車向けアプリ ライブラリのさまざまな機能について詳しく説明します。

マニフェストでナビゲーション サポートを宣言する

ナビゲーション アプリでは、CarAppService のインテント フィルタで自動車アプリのカテゴリとして androidx.car.app.category.NAVIGATION を宣言する必要があります。

<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 アシスタントから取得したものを含む)をサポートするためには、アプリは Session.onCreateScreenSession.onNewIntentCarContext.ACTION_NAVIGATE インテントを処理する必要があります。

インテントの形式について詳しくは、CarContext.startCarApp のドキュメントをご覧ください。

ナビゲーション テンプレートにアクセスする

ナビゲーション アプリは、サーフェスを表示する次のテンプレートにアクセスできます 地図の背景と、アクティブなナビゲーション中はターンバイターン方式のナビが 説明します。

  • NavigationTemplate: ナビゲーション使用時に任意の情報メッセージと推定所要時間も表示します。
  • MapWithContentTemplate: アプリがなんらかのコンテンツ( 例: リスト)。コンテンツは通常、上部にオーバーレイとしてレンダリングされます。 地図タイル。地図は表示可能で、コンテンツに合わせて安定した領域が調整されます。

ナビゲーション アプリのユーザー インターフェースを これらのテンプレートについては、ナビゲーション アプリをご覧ください。

ナビゲーション テンプレートにアクセスするには、AndroidManifest.xml ファイルで androidx.car.app.NAVIGATION_TEMPLATES 権限を宣言する必要があります。

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

地図を描画するには追加の権限が必要です。

MapWithContentTemplate に移行する

Car App API レベル 7 以降では、 MapTemplate PlaceListNavigationTemplate, および RoutePreviewNavigationTemplate は非推奨です。サポートが終了したテンプレートも引き続きサポートされますが、 MapWithContentTemplate に移行することを強くおすすめします。

これらのテンプレートが提供する機能を実装するには MapWithContentTemplate を使用します。次のスニペットで例をご覧ください。

マップ テンプレート

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();

ナビゲーション アプリは、ホストに追加のナビゲーション メタデータを伝える必要があります。ホストはこの情報を使用して、車のヘッドユニットに情報を伝え、共有リソース上のナビゲーション アプリ間の競合を防ぎます。

ナビゲーション メタデータは、CarContext からアクセスできる NavigationManager 自動車サービスより取得できます。

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) を使用します。

状況によって、ホストは、アプリによるナビゲーションの停止を必要とします。このような場合、NavigationManager.setNavigationManagerCallback を使用してアプリが提供する NavigationManagerCallback オブジェクトの onStopNavigation が呼び出されます。この場合、アプリはクラスタ ディスプレイ、ナビゲーション通知、音声案内で、次のターンの情報の提供を停止する必要があります。

ルート情報を更新する

ナビゲーション使用時に、NavigationManager.updateTrip を呼び出します。この呼び出しで提供される情報は、車のクラスタ ディスプレイとヘッドアップ ディスプレイで使用される場合があります。運転中の車の種類によっては、すべての情報がユーザーに表示されるわけではありません。たとえば、デスクトップ ヘッドユニット(DHU)には、Trip に追加された Step は表示されますが、Destination 情報は表示されません。

クラスタ ディスプレイに描画する

車のクラスタ ディスプレイに基本的なメタデータを表示するだけでなく、さらに臨場感のあるユーザー エクスペリエンスを提供したい場合があります。自動車向けアプリの API レベル 6 以降では、ナビゲーション アプリに独自のコンテンツをクラスタ ディスプレイ(サポートしている車の場合)に直接レンダリングするオプションがあります。ただし、次の制限があります。

  • クラスタ ディスプレイ API は入力コントロールをサポートしていません。
  • クラスタ ディスプレイには地図タイルのみが表示されます。これらのタイルには使用中のルート ナビゲーションを表示することもできます。
  • クラスタ ディスプレイ API は NavigationTemplate の使用のみをサポートしています。
    • メイン ディスプレイとは異なり、クラスタ ディスプレイにはターンバイターン方式の指示、ETA カード、アクションなどの NavigationTemplate の UI 要素がすべて、常に表示されるとは限りません。地図タイルのみが常に表示される UI 要素です。

クラスタのサポートを宣言する

アプリがクラスタ ディスプレイでのレンダリングをサポートしていることをホストアプリに伝えるには、次のスニペットのとおり、androidx.car.app.category.FEATURE_CLUSTER <category> 要素を CarAppService<intent-filter> に追加する必要があります。

<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>

ライフサイクルと状態管理

API レベル 6 以降、自動車アプリのライフサイクル フローに変更はありませんが、CarAppService::onCreateSession は作成された Session に関する追加情報を提供する SessionInfo タイプのパラメータを取得するようになりました(すなわち、ディスプレイのタイプとサポートされているテンプレートのセット)。

アプリでは同じ 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 が呼び出された後にのみ、クラスタ ディスプレイをコントロールできるようになります。ただし、ナビゲーションを使用していないときにアプリがクラスタ ディスプレイに表示される場合や、クラスタ ディスプレイにまったく表示されない場合もあります。アプリのアイドル状態時の地図タイルをレンダリングして、このようなシナリオに対応するかどうかはアプリによります。

ホストは Session ごとに別々のバインダと CarContext インスタンスを作成します。つまり、ScreenManager::pushScreen::invalidate などのメソッドを使用する場合、呼び出し元の Session のみが影響を受けます。Session をまたぐ通信が必要な場合、アプリはこれらのインスタンス間の独自の通信チャネルを作成する必要があります(たとえば、ブロードキャストや共有シングルトンなどを使用)。

クラスタのサポートをテストする

Android Auto と Android Automotive OS の両方で実装をテストできます。Android Auto の場合は、デスクトップ ヘッドユニットを構成して、セカンダリ クラスタ ディスプレイをエミュレートすることで、テストできます。Android Automotive OS の場合は、API レベル 30 以上の Generic System Image でクラスタ ディスプレイをエミュレートします。

テキストまたはアイコンを使用して TravelEstimate をカスタマイズする

推定所要時間をテキスト、アイコン、またはその両方を使ってカスタマイズするには、TravelEstimate.Builder クラスの setTripIcon または setTripText メソッドを使用します。NavigationTemplate では TravelEstimate を使用して、予定到着時刻、残り時間、残りの距離とともに(またはその代わりに)テキストやアイコンを表示することもできます。

図 1. カスタムのアイコンとテキストを含む推定所要時間

次のスニペットでは、setTripIconsetTripText を使って推定所要時間をカスタマイズしています。

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)ナビゲーション指示を提供します。車の画面でナビゲーション通知として処理されるようにするには、通知ビルダーで次のことを行う必要があります。

  1. NotificationCompat.Builder.setOngoing メソッドを使用して、通知を進行中としてマークします。
  2. 通知のカテゴリを Notification.CATEGORY_NAVIGATION に設定します。
  3. CarAppExtender を使用して通知を拡張します。

ナビゲーション通知は車の画面下部にあるレール ウィジェットに表示されます。通知の重要度レベルが IMPORTANCE_HIGH に設定されている場合は、ヘッドアップ通知(HUN)としても表示されます。CarAppExtender.Builder.setImportance メソッドで重要度が設定されていない場合は、通知チャンネルの重要度が使用されます。

CarAppExtenderPendingIntent を設定すると、ユーザーが HUN またはレール ウィジェットをタップしたときにアプリに送信されるようにできます。

値が trueNotificationCompat.Builder.setOnlyAlertOnce が呼び出された場合、重要度の高い通知は HUN で 1 回のみアラートとして表示されます。

次のスニペットは、ナビゲーション通知を作成する方法を示しています。

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();

距離の変化に応じて TBT 通知を定期的に更新します。これにより、レール ウィジェットが更新され、通知は HUN としてのみ表示されます。CarAppExtender.Builder.setImportance で通知の重要度を設定することにより、HUN の動作を制御できます。重要度を IMPORTANCE_HIGH に設定すると、HUN が表示されます。他の値に設定した場合は、レール ウィジェットのみ更新されます。

PlaceListNavigationTemplate コンテンツを更新する

ドライバーが PlaceListNavigationTemplate で作成された場所のリストを閲覧しながら、ボタンをタップしてコンテンツを更新できるようにします。リストの更新を有効にするには、OnContentRefreshListener インターフェースの onContentRefreshRequested メソッドを実装し、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 のヘッダーに表示されます。

ユーザーが更新ボタンをクリックすると、OnContentRefreshListener 実装の onContentRefreshRequested メソッドが呼び出されます。onContentRefreshRequested 内で、Screen.invalidate メソッドを呼び出します。次に、ホストはアプリの Screen.onGetTemplate メソッドにコールバックして、更新されたコンテンツを含むテンプレートを取得します。テンプレートの更新について詳しくは、テンプレートのコンテンツを更新するをご覧ください。onGetTemplate から返される次のテンプレートが同じタイプであれば、更新としてカウントされ、テンプレート割り当てにはカウントされません。

音声によるガイダンスを提供する

車載スピーカーでナビゲーション ガイダンスを再生するには、アプリで音声フォーカスをリクエストする必要があります。AudioFocusRequest の一部として、使用量を AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE として設定します。フォーカス ゲインも AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK として設定します。

ナビゲーションをシミュレートする

Google Play ストアへのアプリの送信時に、アプリのナビゲーション機能を検証するために、アプリで 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 では、デフォルトのナビゲーション自動車アプリは、ユーザーが最後に起動したナビゲーション アプリに対応します。ユーザーがアシスタントを介してナビゲーション コマンドを呼び出した場合や、他のアプリがナビゲーションを開始するインテントを送信した場合に、デフォルトのアプリがナビゲーション インテントを受信します。

コンテキスト内のナビゲーション アラートを表示する

Alert は、ナビゲーション画面のコンテキストを離れることなく、ドライバーに重要な情報をオプションのアクションとともに表示します。ドライバーに優れたエクスペリエンスを提供するために、AlertNavigationTemplate 内で機能し、ルートのナビゲーションを妨げることなく、できる限りドライバーが注意散漫にならないようにします。

AlertNavigationTemplate 内でのみ使用できます。NavigationTemplate の外部でユーザーに通知するには、通知を表示するの説明のとおり、ヘッドアップ通知(HUN)の使用を検討してください。

たとえば、Alert を使用して次のことができます。

  • 交通状況の変化など、現在のナビゲーションに関連する最新情報をドライバーに通知します。
  • ドライバーに現在のナビゲーションに関する最新情報(スピード違反取締の有無など)を確認します。
  • ドライバーが途中で誰かを迎えに行くかどうかなど、今後のタスクを提案し、ドライバーがそのタスクを実行するかどうかを確認します。

基本的な形式では、Alert はタイトルと Alert 継続時間で構成されます。継続時間は進行状況バーで表されます。必要に応じて、サブタイトル、アイコン、最大 2 つの Action オブジェクトを追加できます。

図 2. コンテキスト内のナビゲーション アラート

Alert が表示されると、ドライバーの操作によって NavigationTemplate から離れても、その情報が別のテンプレートに引き継がれることはありません。Alert がタイムアウトするか、ユーザーが操作を行うか、アプリが Alert を解除するまで、元の NavigationTemplate が維持されます。

アラートを作成する

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 がタイムアウトした場合、ホストは AlertCallback.onCancel メソッドを AlertCallback.REASON_TIMEOUT の値を指定して呼び出します。その後 AlertCallback.onDismiss メソッドを呼び出します。

  • ドライバーが操作ボタンのいずれかをクリックすると、ホストは Action.OnClickListener を呼び出してから、AlertCallback.onDismiss を呼び出します。

  • Alert がサポートされていない場合、ホストは AlertCallback.onCancelAlertCallback.REASON_NOT_SUPPORTED の値を指定して呼び出します。Alert は表示されていないため、ホストは AlertCallback.onDismiss を呼び出しません。

アラート時間を構成する

アプリのニーズに合わせて、Alert の時間を選択します。ナビゲーション Alert の推奨時間は 10 秒です。ナビゲーション アラートを参照してください。 をご覧ください。

アラートを表示する

Alert を表示するには、アプリの CarContext から利用できる AppManager.showAlert メソッドを呼び出します。

// Show an alert
carContext.getCarService(AppManager.class).showAlert(alert)
  • 現在表示されている Alert の ID と同じ alertIdAlertshowAlert を呼び出すと、何も起こりません。Alert は更新されません。Alert を更新するには、新しい alertId で再作成する必要があります。
  • 現在表示されている Alert とは違う alertIdAlertshowAlert を呼び出すと、現在表示されている Alert が終了します。

アラートを解除する

Alert はタイムアウトやドライバーの操作により自動的に解除されますが、情報が古くなった場合などに Alert を手動で解除することもできます。Alert を解除するには、その AlertalertIddismissAlert メソッドを呼び出します。

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

現在表示されている Alert と一致しない alertIddismissAlert を呼び出した場合、何も起こりません。例外はスローされません。