地図を描画する

次の テンプレートを使用するナビゲーション アプリ、スポット(POI)アプリ、天気アプリは、Surfaceにアクセスして地図を描画できます。

次のテンプレートを使用するには、アプリの 対応する権限のいずれかを<uses-permission>要素で AndroidManifest.xmlファイルに宣言する必要があります。

テンプレート 権限 ガイダンス
NavigationTemplate androidx.car.app.NAVIGATION_TEMPLATES ナビゲーション
MapWithContentTemplate

androidx.car.app.NAVIGATION_TEMPLATES

または

androidx.car.app.MAP_TEMPLATES

ナビゲーション、 スポット、 天気

MapTemplate

(非推奨 )

androidx.car.app.NAVIGATION_TEMPLATES ナビゲーション

PlaceListNavigationTemplate

(非推奨 )

androidx.car.app.NAVIGATION_TEMPLATES ナビゲーション

RoutePreviewNavigationTemplate

(非推奨 )

androidx.car.app.NAVIGATION_TEMPLATES ナビゲーション

リファレンス実装を見る

完全なリファレンス実装については、ナビゲーション サンプルをご覧ください。

サーフェスの権限を宣言する

アプリで使用しているテンプレートに必要な権限に加えて、サーフェスにアクセスするには、アプリの AndroidManifest.xml ファイルで androidx.car.app.ACCESS_SURFACE 権限を宣言する必要があります。

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

サーフェスにアクセスする

ホストが提供する Surface にアクセスするには、 SurfaceCallback を実装し、その実装を AppManager カーサービスに提供する必要があります。現在の Surface は、onSurfaceAvailable() コールバックと onSurfaceDestroyed() コールバックの SurfaceContainer パラメータで SurfaceCallback に渡されます。

Kotlin

carContext.getCarService(AppManager::class.java).setSurfaceCallback(surfaceCallback)

Java

carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);

仮想ディスプレイを使用してコンテンツをレンダリングする

Canvas API を使用して Surface に直接レンダリングするだけでなく、次の例に示すように、VirtualDisplay API と Presentation API を使用して Surface にビューをレンダリングすることもできます。

class HelloWorldSurfaceCallback(context: Context) : SurfaceCallback {
  lateinit var virtualDisplay: VirtualDisplay
  lateinit var presentation: Presentation

  override fun onSurfaceAvailable(surfaceContainer: SurfaceContainer) {
      virtualDisplay = context
          .getSystemService(DisplayManager::class.java)
          .createVirtualDisplay(
              VIRTUAL_DISPLAY_NAME ,
              surfaceContainer.width,
              surfaceContainer.height,
              surfaceContainer.dpi,
              surfaceContainer.surface,
              0
          )

      presentation = Presentation(context, virtualDisplay.display)

      // Instantiate the view to be used as the content view
      val view = ...

      presentation.setContentView(view)
      presentation.show()
  }

  override fun onSurfaceDestroyed(surfaceContainer: SurfaceContainer) {
    presentation.dismiss()
    // This handles releasing the Surface provided when creating the VirtualDisplay
    virtualDisplay.release()
  }
}

Compose を使用して仮想ディスプレイにレンダリングする

ComposeView を Presentation のコンテンツ ビューとして使用できます。ComposeView はアクティビティの外部で使用されるため、親ビューがLifecycleOwner と SavedStateRegistryOwner を伝播することを確認してください。これを行うには、setViewTreeLifecycleOwner と setViewTreeSavedStateRegistryOwner を使用します。

Session はすでに LifecycleOwner を実装しています。両方のロールを処理するには、実装で SavedStateRegistryOwner を追加で実装します。

class HelloWorldSession() : Session(), SavedStateRegistryOwner { ... }

class HelloWorldSurfaceCallback(session: HelloWorldSession) : SurfaceCallback {
  ...

  override fun onSurfaceAvailable(surfaceContainer: SurfaceContainer) {
    ...
    val view = ComposeView(session.carContext)
    view.setViewTreeLifecycleOwner(session)
    view.setViewTreeSavedStateRegistryOwner(session)
    view.setContent {
      // Composable content
    }

    presentation.setContentView(view)
    presentation.show()
  }

  ...
}

サーフェスの表示領域を理解する

ホストはテンプレートのユーザー インターフェース要素を地図上に描画できます。 ホストは SurfaceCallback.onVisibleAreaChanged メソッド を呼び出して、遮るものがなく、 ユーザーに表示される可能性が最も高いサーフェスの領域を伝えます。

変更回数を最小限に抑えるために、ホストは SurfaceCallback.onStableAreaChanged メソッドを呼び出します。この呼び出しでは、現在のテンプレートに基づいて常に表示される最小の長方形が使用されます。

たとえば、ナビゲーション アプリが NavigationTemplate を使用していて、上部に アクション ストリップがある場合、ユーザーが画面を操作しなければアクション ストリップ自体を非表示にして、画面上のスペースを増やすことができます。この場合、同じ長方形で onStableAreaChanged と onVisibleAreaChanged へのコールバックが行われます。

アクション ストリップが非表示になると、より大きな領域で onVisibleAreaChanged のみが呼び出されます。ユーザーが画面を操作すると、最初の長方形で onVisibleAreaChanged のみが呼び出されます。

ダークモードをサポートする

条件を満たしているとホストが判断した場合、ナビゲーション アプリは自動車向け Android アプリの品質の説明のとおり、適切な暗い 色を使用して Surface インスタンスに地図を再描画する必要があります。

暗い色の地図を描画するには、CarContext.isDarkMode メソッドを使用します。ダーク モードのステータスが変更されると、 Session.onCarConfigurationChanged の呼び出しを受け取ります。

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

ナビゲーション アプリは、メインディスプレイに地図を描画するだけでなく、ステアリング ホイールの後ろにあるクラスタ ディスプレイに地図を描画することもできます。詳細については、クラスタ ディスプレイに描画するをご覧ください。