地図を描画する

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

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

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

androidx.car.app.NAVIGATION_TEMPLATES

または、

androidx.car.app.MAP_TEMPLATES

ナビゲーションPOI天気

MapTemplate

非推奨

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

PlaceListNavigationTemplate

非推奨

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

RoutePreviewNavigationTemplate

非推奨

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

リファレンス実装を参照する

完全なリファレンス実装については、Navigation サンプルをご覧ください。

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

アプリが使用しているテンプレートに必要な権限に加えて、サーフェスにアクセスするには、アプリの 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 に View をレンダリングすることもできます。

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 を使用して仮想ディスプレイにレンダリングする

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

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 を使用していて、上部にアクション ストリップがある場合、ユーザーが画面を操作していないときにアクション ストリップを非表示にして、画面のスペースを広げることができます。この場合、onStableAreaChangedonVisibleAreaChanged へのコールバックは同じ長方形で行われます。

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

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

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

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

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

ナビゲーション アプリは、メインディスプレイに地図を描画するだけでなく、ハンドルの背後にあるクラスタ ディスプレイに地図を描画することもサポートできます。詳しくは、クラスタ表示への描画をご覧ください。