Disegna mappe

Le app di navigazione, punti di interesse (PDI) e meteo che utilizzano i seguenti modelli possono disegnare mappe accedendo a un Surface.

Per utilizzare i seguenti modelli, la tua app deve dichiarare una di queste autorizzazioni corrispondenti in un elemento <uses-permission> nel file AndroidManifest.xml.

Modello Autorizzazione Assistenza
NavigationTemplate androidx.car.app.NAVIGATION_TEMPLATES Navigazione
MapWithContentTemplate

androidx.car.app.NAVIGATION_TEMPLATES

o

androidx.car.app.MAP_TEMPLATES

Navigazione, PDI, Meteo

MapTemplate

(deprecato)

androidx.car.app.NAVIGATION_TEMPLATES Navigazione

PlaceListNavigationTemplate

(deprecato)

androidx.car.app.NAVIGATION_TEMPLATES Navigazione

RoutePreviewNavigationTemplate

(deprecato)

androidx.car.app.NAVIGATION_TEMPLATES Navigazione

Visualizza l'implementazione di riferimento

Per visualizzare un'implementazione di riferimento completa, consulta Esempio di navigazione.

Dichiarare l'autorizzazione Surface

Oltre all'autorizzazione richiesta per il modello utilizzato dalla tua app, la tua app deve dichiarare l'autorizzazione androidx.car.app.ACCESS_SURFACE nel file AndroidManifest.xml per ottenere l'accesso alla superficie:

<manifest ...>
  ...
  <uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
  ...
</manifest>

Accedere alla piattaforma

Per accedere al Surface fornito dall'host, devi implementare un SurfaceCallback e fornirlo al servizio di AppManager auto. L'attuale Surface viene passato al tuo SurfaceCallback nel parametro SurfaceContainer dei callback onSurfaceAvailable() e onSurfaceDestroyed().

Kotlin

carContext.getCarService(AppManager::class.java).setSurfaceCallback(surfaceCallback)

Java

carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);

Utilizzare un display virtuale per il rendering dei contenuti

Oltre al rendering direttamente in Surface utilizzando l'API Canvas, puoi anche eseguire il rendering delle visualizzazioni in Surface utilizzando le API VirtualDisplay e Presentation, come mostrato in questo esempio:

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()
  }
}

Utilizza Compose per il rendering sul display virtuale

Puoi utilizzare un ComposeView come visualizzazione dei contenuti del Presentation. Poiché ComposeView viene utilizzato al di fuori di un'attività, verifica che lui o una visualizzazione principale propagano un LifecycleOwner e un SavedStateRegistryOwner. Per farlo, utilizza setViewTreeLifecycleOwner e setViewTreeSavedStateRegistryOwner.

Session implementa già LifecycleOwner. Per svolgere entrambi i ruoli, la tua implementazione può anche implementare 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()
  }

  ...
}

Informazioni sull'area visibile della superficie

L'host può disegnare gli elementi dell'interfaccia utente per i modelli sopra la mappa. L'host chiama il metodo SurfaceCallback.onVisibleAreaChanged per comunicare l'area della superficie più probabilmente libera e visibile all'utente.

Per ridurre al minimo il numero di modifiche, l'host chiama il metodo SurfaceCallback.onStableAreaChanged con il rettangolo più piccolo, che è sempre visibile in base al modello corrente.

Ad esempio, quando un'app di navigazione utilizza NavigationTemplate con una barra delle azioni nella parte superiore, per creare più spazio sullo schermo la barra delle azioni può essere nascosta quando l'utente non ha interagito con lo schermo. Questo caso comporta un richiamo a onStableAreaChanged e onVisibleAreaChanged con lo stesso rettangolo.

Quando la barra delle azioni è nascosta, viene chiamato solo onVisibleAreaChanged con l'area più grande. Se l'utente interagisce con lo schermo, viene chiamato solo onVisibleAreaChanged con il primo rettangolo.

Supportare il tema scuro

Le app devono ridisegnare la mappa nell'istanza Surface con i colori scuri appropriati quando l'host determina che le condizioni lo giustificano, come descritto in Qualità delle app per Android per le auto.

Per disegnare una mappa scura, utilizza il metodo CarContext.isDarkMode. Quando lo stato del tema scuro cambia, ricevi una chiamata al numero Session.onCarConfigurationChanged.

Disegnare mappe sul display del cluster

Oltre a disegnare mappe sul display principale, le app di navigazione possono anche supportare il disegno di mappe sul display del quadro strumenti dietro il volante. Per saperne di più, consulta la sezione Disegno sul display del quadro strumenti.