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 elemento <uses-permission> no arquivo
AndroidManifest.xml.
| Modelo | Permissão | Orientação |
|---|---|---|
NavigationTemplate |
androidx.car.app.NAVIGATION_TEMPLATES |
Navegação |
MapWithContentTemplate |
ou
|
Navegação, Ponto de interesse, Clima |
|
(descontinuado) |
androidx.car.app.NAVIGATION_TEMPLATES |
Navegação |
|
(descontinuado) |
androidx.car.app.NAVIGATION_TEMPLATES |
Navegação |
(descontinuado) |
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 exibição
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 à plataforma:
<manifest ...>
...
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
...
</manifest>
Acessar a plataforma
Para acessar o Surface fornecido pelo host, implemente um
SurfaceCallback e forneça essa implementação ao serviço de carro
AppManager. O Surface atual é transmitido para seu SurfaceCallback no parâmetro SurfaceContainer 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 no Surface usando a API Canvas,
você também pode renderizar Views no 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 um ComposeView como a visualização de conteúdo do Presentation. Como ComposeView é usado fora de uma atividade, confirme se ele ou uma visualização principal propaga um LifecycleOwner e um SavedStateRegistryOwner. Para 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.
O host chama o método SurfaceCallback.onVisibleAreaChanged
para comunicar a área da superfície que provavelmente não estará obstruída e
visível para o usuário.
Para minimizar o número de mudanças, o host chama o método
SurfaceCallback.onStableAreaChanged 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 liberar mais espaço na tela, a faixa de ação pode
ser ocultada quando o usuário não interage com a tela. Nesse caso, há 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.
Oferecer suporte ao tema escuro
Os apps precisam redesenhar o mapa na instância de Surface com as cores escuras adequadas quando o host determinar que as condições justificam esse uso, conforme descrito em Qualidade do app Android para carros.
Para desenhar um mapa escuro, use o método CarContext.isDarkMode. 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 desenhar mapas na tela do cluster atrás do volante. Para saber mais, consulte Desenhar na tela do cluster.