Приложения для навигации, отображения точек интереса (POI) и прогноза погоды, использующие следующие шаблоны, могут создавать карты, обращаясь к Surface .
Для использования следующих шаблонов ваше приложение должно объявить одно из соответствующих разрешений в элементе <uses-permission> в файле AndroidManifest.xml .
| Шаблон | Разрешение | Руководство |
|---|---|---|
NavigationTemplate | androidx.car.app.NAVIGATION_TEMPLATES | Навигация |
MapWithContentTemplate | или, | Навигация , POI , Погода |
( устарело ) | androidx.car.app.NAVIGATION_TEMPLATES | Навигация |
( устарело ) | androidx.car.app.NAVIGATION_TEMPLATES | Навигация |
( устарело ) | androidx.car.app.NAVIGATION_TEMPLATES | Навигация |
См. эталонную реализацию.
Чтобы ознакомиться с полной эталонной реализацией, см. пример навигации .
Укажите разрешение на использование поверхности.
В дополнение к разрешениям, необходимым для используемого вашим приложением шаблона, ваше приложение должно объявить разрешение androidx.car.app.ACCESS_SURFACE в файле AndroidManifest.xml , чтобы получить доступ к поверхности:
<manifest ...>
...
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
...
</manifest>
Доступ к поверхности
Для доступа к Surface , предоставляемой хостом, необходимо реализовать SurfaceCallback и передать эту реализацию в службу AppManager . Текущая Surface передается в SurfaceCallback в параметре SurfaceContainer в коллбэках onSurfaceAvailable() и onSurfaceDestroyed() .
Котлин
carContext.getCarService(AppManager::class.java).setSurfaceCallback(surfaceCallback)
Java
carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);
Используйте виртуальный дисплей для отображения контента.
Помимо непосредственного рендеринга на Surface с использованием API Canvas , вы также можете рендерить представления на Surface с помощью API VirtualDisplay и Presentation , как показано в этом примере:
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 используется вне активности, убедитесь, что он или родительское представление передаёт свойства 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 вызывается только для первого прямоугольника.
Поддержка темной темы
Приложения должны перерисовывать свою карту на экземпляре Surface с соответствующими темными цветами, когда хост определяет, что этого требуют условия, как описано в разделе «Качество приложений Android для автомобилей» .
Для отображения карты в темном режиме используйте метод CarContext.isDarkMode . При изменении статуса темной темы вы получите вызов метода Session.onCarConfigurationChanged .
Нарисуйте карты на кластерном дисплее.
Помимо отображения карт на основном дисплее, навигационные приложения также могут поддерживать отображение карт на дисплее приборной панели за рулевым колесом. Для получения дополнительной информации см. раздел «Отображение на дисплее приборной панели» .