다음 템플릿을 사용하는 내비게이션, 관심 장소 (POI), 날씨 앱은 Surface에 액세스하여 지도를 그릴 수 있습니다.
다음 템플릿을 사용하려면 앱이 AndroidManifest.xml 파일의 <uses-permission> 요소에 해당하는 권한 중 하나를 선언해야 합니다.
| 템플릿 | 권한 | 가이드 |
|---|---|---|
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)
자바
carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);
가상 디스플레이를 사용하여 콘텐츠 렌더링
Canvas API를 사용하여 Surface에 직접 렌더링하는 것 외에도 이 예와 같이 VirtualDisplay 및 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가 활동 외부에서 사용되므로 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 호출을 수신합니다.
클러스터 디스플레이에 지도 그리기
내비게이션 앱은 기본 디스플레이에 지도를 그리는 것 외에도 핸들 뒤의 클러스터 디스플레이에 지도를 그리는 것을 지원할 수 있습니다. 자세한 내용은 클러스터 디스플레이에 그리기를 참고하세요.