地図を描画する

次の テンプレートを使用するナビゲーション アプリ、スポット(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 を使用して仮想ディスプレイにレンダリングする

ComposeViewPresentation のコンテンツ ビューとして使用できます。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 の呼び出しを受け取ります。

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

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