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