このセクションでは、ターンバイターン方式のナビゲーション アプリの機能を実装するための、ライブラリの各機能について詳しく説明します。
マニフェストでナビゲーション サポートを宣言する
ナビゲーション アプリでは、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.onCreateScreen
と Session.onNewIntent
の中で CarContext.ACTION_NAVIGATE
インテントを処理する必要があります。
インテントの形式について詳しくは、CarContext.startCarApp
のドキュメントをご覧ください。
ナビゲーション テンプレートにアクセスする
ナビゲーション アプリは、ナビゲーション アプリ専用に設計された以下のテンプレートにアクセスできます。これらのテンプレートはすべて、地図を描画するためにアプリがアクセスできるサーフェスを背景に表示するとともに、テンプレートごとに異なる、アプリ提供の情報を表示します。
NavigationTemplate
: 地図を表示します。必要に応じて、アクティブなナビゲーション中に、情報メッセージ、経路案内、所要時間も表示します。MapTemplate
: リスト(ListTemplate
にあるようなリスト)またはペイン(PaneTemplate
にあるような目立つアクションを伴う詳細情報)のコンパクトなバージョンを表示します。PlaceListNavigationTemplate
: 場所のリストを表示します。これらの場所に対応するマーカーを地図上に描画できます。RoutePreviewNavigationTemplate
: 経路のリストを表示します。これらの経路のひとつを選択して、地図上でハイライト表示できます。
これらのテンプレートを使用してナビゲーション アプリのユーザー インターフェースを設計する方法について詳しくは、自動車向け Android アプリ ライブラリの設計ガイドラインをご覧ください。
ナビゲーション テンプレートにアクセスするには、アプリは AndroidManifest.xml
で androidx.car.app.NAVIGATION_TEMPLATES
権限を宣言する必要があります。
<uses-permission android:name="androidx.car.app.NAVIGATION_TEMPLATES"/>
地図の描画
ナビゲーション アプリは、適用するテンプレート上で地図を描画するために Surface
にアクセスできます。
SurfaceContainer
オブジェクトにアクセスするには、SurfaceCallback
インスタンスを AppManager
自動車サービスに設定します。
Kotlin
carContext.getCarService(AppManager::class.java).setSurfaceCallback(surfaceCallback)
Java
carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);
SurfaceCallback
は、SurfaceContainer
が利用可能な場合のコールバックのほか、Surface
のプロパティが変更された場合の他のコールバックを提供します。
サーフェスにアクセスするには、アプリは AndroidManifest.xml
で androidx.car.app.ACCESS_SURFACE
権限を宣言する必要があります。
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE"/>
地図の表示エリア
ホストは、地図上にさまざまなテンプレートのユーザー インターフェース要素を描画できます。ホストは、SurfaceCallback.onVisibleAreaChanged
メソッドを呼び出すことで、遮るものがなく、ユーザーに完全に表示されることが保証されている領域を伝えます。また、変更回数を最小限に抑えるために、ホストは SurfaceCallback.onStableAreaChanged
メソッドを呼び出します。この呼び出しでは現在のテンプレートに基づいて常に表示される最小の長方形が使用されます。
たとえば、ナビゲーション アプリが NavigationTemplate
を使用していて、上部にアクション ストリップがある場合、ユーザーがしばらく画面を操作しなければアクション ストリップ自体が非表示になり、地図用のスペースが増えます。この場合、onStableAreaChanged
と onVisibleAreaChanged
へのコールバックは同じ長方形で行われます。アクション ストリップが非表示になると、onVisibleAreaChanged
のみがより大きい領域で呼び出されます。ユーザーが画面を操作すると、最初の長方形で onVisibleAreaChanged
のみが再度呼び出されます。
ダークモード
条件が満たされているとホストが判断した場合、ナビゲーション アプリは、Android Auto アプリの品質に関するガイドラインの説明のとおり、適切な暗い色を使用して Surface
インスタンスに地図を再描画する必要があります。
暗い地図を描くかどうかを決定するには、CarContext.isDarkMode
メソッドを使用します。ダークモードのステータスが変更されるたびに、Session.onCarConfigurationChanged
の呼び出しを受け取ります。
ナビゲーション メタデータ
ナビゲーション アプリは、ホストに追加のナビゲーション メタデータを伝える必要があります。ホストはこの情報を使用して、車のヘッドユニットに情報を伝え、共有リソース上のナビゲーション アプリ間の競合を防ぎます。
ナビゲーション メタデータは、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.setListener
を使用してアプリが提供する NavigationManagerListener
オブジェクトの stopNavigation
が呼び出されます。するとアプリは、クラスタ表示、ナビゲーション通知、音声案内で、次のターンの情報の発行を停止しなければならなくなります。
ルート情報
アクティブなナビゲーション中に、アプリは NavigationManager.updateTrip
を呼び出す必要があります。この呼び出しで提供される情報は、車のクラスタ ディスプレイとヘッドアップ ディスプレイで使用される場合があります。運転中の車によっては、一部の情報がユーザーに表示されない場合があります。たとえば、デスクトップ ヘッドユニット(DHU)には、Trip
に追加された Step
は表示されますが、Destination
情報は表示されません。
テキストやアイコンを使用して TravelEstimate をカスタマイズする
テキストやアイコンで推定所要時間をカスタマイズするには、TravelEstimate.Builder
の setTripIcon
メソッド、または setTripText
メソッドを使用します。NavigationTemplate
では、必要に応じて TravelEstimate
を使用して、予定到着時刻、残り時間、残りの距離とともに(またはその代わりに)テキストやアイコンを表示します。

次のスニペットでは、TravelEstimate.Builder
の 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)方式のナビゲーション指示を提供できます。車の画面でナビゲーション通知として処理されるようにするには、通知ビルダーで以下を行う必要があります。
NotificationCompat.Builder.setOngoing
メソッドを使用して、通知を進行中としてマークします。- 通知のカテゴリを
Notification.CATEGORY_NAVIGATION
に設定します。 CarAppExtender
を使用して通知を拡張します。
ナビゲーション通知は車の画面下部にあるレール ウィジェットに表示されます。通知の重要度レベルが IMPORTANCE_HIGH
に設定されている場合は、ヘッドアップ通知(HUN)としても表示されます。CarAppExtender.Builder.setImportance
メソッドで重要度が設定されていない場合は、通知チャンネルの重要度が使用されます。
アプリは、ユーザーが HUN またはレール ウィジェットをタップしたときにアプリに送信される PendingIntent
を CarAppExtender
で設定できます。
値を true
に指定して NotificationCompat.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 では、デフォルトのナビゲーション自動車アプリは、ユーザーが最後に起動したナビゲーション アプリに対応します。たとえば、ユーザーがアシスタントを介してナビゲーション コマンドを呼び出した場合や、他のアプリからナビゲーションを開始するためにインテントを送信すると、このアプリがナビゲーション インテントを受信します。
ユーザーに地図の操作を許可する
地図のズームやパンなど、ユーザーが地図のさまざまな部分を表示できるようサポートする機能を追加できます。テンプレートごとに、Car App API の最小レベル要件が異なります。実装するテンプレートの最小レベルについては、下記の表をご覧ください。
テンプレート | インタラクティビティをサポートする Car App API レベル |
---|---|
NavigationTemplate | 2 |
PlaceListNavigationTemplate | 4 |
RoutePreviewNavigationTemplate | 4 |
MapTemplate | 5 |
SurfaceCallback メソッド
SurfaceCallback
には、NavigationTemplate
、PlaceListNavigationTemplate
、RoutePreviewNavigationTemplate
、または MapTemplate
テンプレートで作成したマップにマップ インタラクティビティを追加するためのコールバック メソッドが用意されています(onClick
、onScroll
、onScale
、onFling
)。これらのコールバックとユーザーの操作との関連については、次の表をご覧ください。
操作 | SurfaceCallback メソッド |
サポートする Car App API レベル |
---|---|---|
タップ | onClick |
5 |
ピンチ(ズーム) | onScale |
2 |
シングルタップ ドラッグ | onScroll |
2 |
シングルタップ フリング | onFling |
2 |
ダブルタップ | onScale (テンプレート ホストによってスケーリング ファクタが決定される) |
2 |
パンモードの回転ナッジ | onScroll (テンプレート ホストによって距離ファクタが決定される) |
2 |
マップ アクション ストリップ
NavigationTemplate
、PlaceListNavigationTemplate
、RoutePreviewNavigationTemplate
、および MapTemplate
テンプレートでは、地図に関連する操作(拡大 / 縮小、センタリング、コンパスの表示など、アプリで可能にする操作)に対応する、マップ アクション ストリップを設定できます。マップ アクション ストリップには、タスクの階層を変更することなく更新できる、アイコンのみのボタンを 4 つまで設定できます。アクション ストリップと同様に、マップ アクション ストリップはアイドル状態には非表示になり、アクティブ状態になると表示されます。
マップ インタラクティビティ コールバックを受け取るようにするには、マップ アクション ストリップに Action.PAN
ボタンを追加する必要があります。アプリのマップ アクション ストリップに Action.PAN
ボタンを設定しないと、SurfaceCallback
メソッドからユーザー入力を取得できず、ホストで有効になっていたパンモードが終了します。ユーザーがパンボタンを押すと、ホストがパンモードに切り替わります。パンボタンはタッチスクリーンには表示されません。
パンモード
パンモードでは、ノンタップの入力デバイス(ロータリー コントローラやタッチパッドなど)からのユーザー入力が、テンプレート ホストによって適切な SurfaceCallback
メソッドに変換されます。パンモードを開始または終了するユーザー操作に応答するには、NavigationTemplate
Builder
の setPanModeListener
メソッドを使用します。ユーザーがパンモードになっている間は、他の UI コンポーネントを非表示にできます。
安定領域
安定領域は、アイドル状態とアクティブ状態の間に更新されます。アプリで速度、速度制限、道路警告などの運転関連の情報を表示させる場合は、地図上の重要な情報がマップ アクション ストリップによって遮られないように、安定領域のサイズに応じて情報が取得されるようにします。
コンテキスト内のナビゲーション アラート
Alert
は、ナビゲーション画面のコンテキストを離れることなく、ドライバーに重要な情報をオプションのアクションとともに表示します。ドライバーに最高のエクスペリエンスを提供するために、Alert
は NavigationTemplate
内で動作し、ルートのナビゲーションを妨げることなく、できるだけドライバーの注意がおろそかにならないようにします。
Alert
は NavigationTemplate
内でのみ使用できます。NavigationTemplate
の外部でユーザーに通知するには、ディスプレイ通知で説明されているように、ヘッドアップ通知(HUN)の使用を検討してください。
たとえば、Alert
を使用して次のことを行います。
- 交通状況の変化など、現在のナビゲーションに関連する最新情報をドライバーに通知します。
- ドライバーに、現在のナビゲーションに関する最新情報(スピード違反取締の有無など)を確認します。
- ドライバーが途中で誰かを迎えに行くかどうかなど、予定されるタスクを提案し、ドライバーがそれを受け入れるかどうか確認します。
基本的な形式では、Alert
はタイトルと Alert
継続時間で構成されます。継続時間は進行状況バーで表されます。必要に応じて、サブタイトル、アイコン、最大 2 つの Action
を追加できます。

Alert
が表示されると、ドライバーの操作によって NavigationTemplate
から離れても、対応する情報が別のテンプレートに引き継がれることはありません。
Alert
がタイムアウトするか、ユーザーが操作を行うか、アプリが Alert
を解除するまで、元の NavigationTemplate
が維持されます。
アラート時間を設定する
アプリのニーズに合わせて、Alert
の時間を選択します。ナビゲーション Alert
の推奨時間は 10 秒です。自動車向け Android の設計ガイドラインを参考にしてください。
アラートを作成する
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.onCancel
をAlertCallback.REASON_NOT_SUPPORTED
の値そ指定した状態で呼び出します(Alert
が表示されなかったため、ホストはAlertCallback.onDismiss
を呼び出しません)。
アラートを表示する
Alert
を表示するには、アプリの CarContext
を通じて利用できる AppManager.showAlert
メソッドを呼び出します。
// Show an alert
carContext.getCarService(AppManager.class).showAlert(alert)
showAlert
を呼び出すときに、使用するAlert
が現在表示されているAlert
と同じalertId
を持つ場合、何も起こりません(Alert
は更新されません。Alert
を更新するには、Alert
を新しいalertId
で再作成する必要があります)。showAlert
を呼び出すとき、使用するAlert
が現在表示されているAlert
とは異なるalertId
を持つ場合、現在表示されているAlert
は解除されます。
アラートを解除する
Alert
はタイムアウトやドライバーの操作により自動的に解除されますが、Alert
を手動で解除することもできます。たとえば、Alert
の情報が古くなったため、これを解除したいとします。Alert
を解除するには、Alert
の alertId
で dismissAlert
メソッドを呼び出します。
// Dismiss the same alert
carContext.getCarService(AppManager.class).dismissAlert(alert.getId())
dismissAlert
を呼び出すとき、使用する alertId
が現在表示されている Alert
(存在する場合)と一致しない場合、何も起こりません(例外はスローされません)。