Aplikacje do nawigacji, prezentujące ciekawe miejsca i pogodowe, które korzystają z tych
szablonów, mogą rysować mapy, uzyskując dostęp do Surface.
Aby korzystać z tych szablonów, aplikacja musi zadeklarować jedno z tych
uprawnień w elemencie <uses-permission> w pliku
AndroidManifest.xml.
| Szablon | Uprawnienie | Wskazówki |
|---|---|---|
NavigationTemplate |
androidx.car.app.NAVIGATION_TEMPLATES |
Nawigacja |
MapWithContentTemplate |
lub
|
Nawigacja, ciekawe miejsca, pogoda |
|
(wycofany) |
androidx.car.app.NAVIGATION_TEMPLATES |
Nawigacja |
|
(wycofany) |
androidx.car.app.NAVIGATION_TEMPLATES |
Nawigacja |
(wycofany) |
androidx.car.app.NAVIGATION_TEMPLATES |
Nawigacja |
Zobacz implementację referencyjną
Aby zobaczyć pełną implementację referencyjną, zapoznaj się z przykładem nawigacji.
Zadeklaruj uprawnienie do powierzchni
Oprócz uprawnienia wymaganego przez szablon, którego używa Twoja aplikacja, musi ona też zadeklarować uprawnienie androidx.car.app.ACCESS_SURFACE w pliku AndroidManifest.xml, aby uzyskać dostęp do powierzchni:
<manifest ...>
...
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
...
</manifest>
Dostęp do powierzchni
Aby uzyskać dostęp do Surface udostępnianej przez hosta, musisz zaimplementować
SurfaceCallback i przekazać tę implementację do AppManager
usługi samochodowej. Bieżąca Surface jest przekazywana do SurfaceCallback w parametrze
SurfaceContainer wywołań zwrotnych onSurfaceAvailable() i
onSurfaceDestroyed().
Kotlin
carContext.getCarService(AppManager::class.java).setSurfaceCallback(surfaceCallback)
Java
carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);
Używanie wirtualnego wyświetlacza do renderowania treści
Oprócz renderowania bezpośrednio na Surface za pomocą interfejsu API Canvas możesz też renderować widoki na Surface za pomocą interfejsów API VirtualDisplay i Presentation, jak pokazano w tym przykładzie:
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()
}
}
Używanie Compose do renderowania na wirtualnym wyświetlaczu
Możesz użyć ComposeView jako widoku treści Presentation. Ponieważ ComposeView jest używany poza aktywnością, upewnij się, że on lub widok rodzica propaguje LifecycleOwner i SavedStateRegistryOwner. Aby to zrobić, użyj setViewTreeLifecycleOwner i setViewTreeSavedStateRegistryOwner.
Session implementuje już LifecycleOwner. Aby pełnić obie role, implementacja może dodatkowo implementować 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()
}
...
}
Poznawanie widocznego obszaru powierzchni
Host może rysować elementy interfejsu użytkownika dla szablonów na mapie.
Host wywołuje metodę SurfaceCallback.onVisibleAreaChanged
, aby przekazać obszar powierzchni, który najprawdopodobniej nie będzie zasłonięty i
będzie widoczny dla użytkownika.
Aby zminimalizować liczbę zmian, host wywołuje metodę
SurfaceCallback.onStableAreaChanged z najmniejszym prostokątem,
który jest zawsze widoczny zgodnie z bieżącym szablonem.
Na przykład, gdy aplikacja do nawigacji używa NavigationTemplate z
paskiem działań u góry, aby zwolnić więcej miejsca na ekranie, pasek działań może
być ukryty, gdy użytkownik nie wchodzi w interakcję z ekranem. W takim przypadku wywołanie zwrotne onStableAreaChanged i onVisibleAreaChanged jest wywoływane z tym samym prostokątem.
Gdy pasek działań jest ukryty, wywoływana jest tylko funkcja onVisibleAreaChanged z większym obszarem. Jeśli użytkownik wejdzie w interakcję z ekranem, wywoływana jest tylko funkcja onVisibleAreaChanged z pierwszym prostokątem.
Obsługa ciemnego motywu
Aplikacje muszą ponownie narysować mapę na instancji Surface z odpowiednimi ciemnymi
kolorami, gdy host stwierdzi, że jest to konieczne, zgodnie z opisem w
artykule Jakość aplikacji na Androida w samochodach.
Aby narysować ciemną mapę, użyj metody CarContext.isDarkMode. Gdy zmieni się stan ciemnego
motywu, otrzymasz wywołanie
Session.onCarConfigurationChanged.
Rysowanie map na wyświetlaczu deski rozdzielczej
Oprócz rysowania map na wyświetlaczu głównym aplikacje do nawigacji mogą też obsługiwać rysowanie map na wyświetlaczu deski rozdzielczej za kierownicą. Więcej informacji znajdziesz w artykule Rysowanie na wyświetlaczu deski rozdzielczej.