Os apps de navegação, ponto de interesse (PDI) e clima que usam os seguintes
modelos podem desenhar mapas acessando um Surface.
Para usar os modelos a seguir, seu app precisa declarar uma dessas
permissões correspondentes em um <uses-permission> elemento no
AndroidManifest.xml arquivo.
| Modelo | Permissão | Orientação |
|---|---|---|
NavigationTemplate |
androidx.car.app.NAVIGATION_TEMPLATES |
Navegação |
MapWithContentTemplate |
ou
|
Navegação, PDI, clima |
|
(obsoleto) |
androidx.car.app.NAVIGATION_TEMPLATES |
Navegação |
|
(obsoleto) |
androidx.car.app.NAVIGATION_TEMPLATES |
Navegação |
(obsoleto) |
androidx.car.app.NAVIGATION_TEMPLATES |
Navegação |
Consulte a implementação de referência
Para conferir uma implementação de referência completa, consulte o exemplo de navegação.
Declarar a permissão de superfície
Além da permissão necessária para o modelo que seu app está usando, ele precisa declarar a permissão androidx.car.app.ACCESS_SURFACE no arquivo AndroidManifest.xml para ter acesso à superfície:
<manifest ...>
...
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
...
</manifest>
Acessar a superfície
Para acessar o Surface fornecido pelo host, implemente um
SurfaceCallback e forneça essa implementação ao AppManager
serviço de carro. A Surface atual é transmitida ao SurfaceCallback no
SurfaceContainer parâmetro dos callbacks onSurfaceAvailable() e
onSurfaceDestroyed().
Kotlin
carContext.getCarService(AppManager::class.java).setSurfaceCallback(surfaceCallback)
Java
carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);
Usar uma tela virtual para renderizar conteúdo
Além de renderizar diretamente na Surface usando a API Canvas, também é possível renderizar visualizações na Surface usando as APIs VirtualDisplay e Presentation, como mostra este exemplo:
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()
}
}
Usar o Compose para renderizar na tela virtual
Você pode usar uma ComposeView como a visualização de conteúdo da Presentation. Como a ComposeView é usada fora de uma Activity, confirme se ela ou uma visualização da família propaga um LifecycleOwner e SavedStateRegistryOwner. Para fazer isso, use setViewTreeLifecycleOwner e setViewTreeSavedStateRegistryOwner.
Session já implementa LifecycleOwner. Para atender às duas funções, sua implementação também pode implementar 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()
}
...
}
Entender a área visível da superfície
O host pode desenhar elementos da interface do usuário para os modelos na parte de cima do mapa.
Ele chama o SurfaceCallback.onVisibleAreaChanged método
para comunicar a área da superfície com maior probabilidade de não estar obstruída e
visível para o usuário.
Para minimizar o número de mudanças, o host chama o
SurfaceCallback.onStableAreaChanged método com o menor retângulo,
que sempre fica visível de acordo com o modelo atual.
Por exemplo, quando um app de navegação usa o NavigationTemplate com uma
faixa de ação na parte de cima, para criar mais espaço na tela, a faixa de ação pode
ser ocultada quando o usuário não interage com a tela. Esse caso resulta em um callback para onStableAreaChanged e onVisibleAreaChanged com o mesmo retângulo.
Quando a faixa de ação está oculta, somente onVisibleAreaChanged é chamado com a área maior. Se o usuário interagir com a tela, apenas onVisibleAreaChanged será chamado com o primeiro retângulo.
Suporte ao tema escuro
Os apps precisam redesenhar o mapa na instância de Surface com as cores escuras adequadas
quando o host determina que as condições justificam esse uso, conforme descrito em
Qualidade do app Android para carros.
Para desenhar um mapa escuro, use o CarContext.isDarkMode método. Quando o status do tema escuro
muda, você recebe uma chamada para
Session.onCarConfigurationChanged.
Desenhar mapas na tela do cluster
Além de desenhar mapas na tela principal, os apps de navegação também podem oferecer suporte ao desenho de mapas na tela do cluster atrás do volante. Para saber mais, consulte Como desenhar na tela do cluster.