次のテンプレートを使用するナビゲーション アプリ、スポット(POI)アプリ、天気アプリは、Surface にアクセスして地図を描画できます。
次のテンプレートを使用するには、アプリが AndroidManifest.xml ファイルの <uses-permission> 要素で、対応する権限のいずれかを宣言する必要があります。
| テンプレート | 権限 | ガイダンス |
|---|---|---|
NavigationTemplate |
androidx.car.app.NAVIGATION_TEMPLATES |
ナビゲーション |
MapWithContentTemplate |
または、
|
ナビゲーション、POI、天気 |
|
(非推奨) |
androidx.car.app.NAVIGATION_TEMPLATES |
ナビゲーション |
|
(非推奨) |
androidx.car.app.NAVIGATION_TEMPLATES |
ナビゲーション |
(非推奨) |
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 または親ビューが 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 の呼び出しを受け取ります。
クラスタ ディスプレイに地図を描画する
ナビゲーション アプリは、メインディスプレイに地図を描画するだけでなく、ハンドルの背後にあるクラスタ ディスプレイに地図を描画することもサポートできます。詳しくは、クラスタ表示への描画をご覧ください。