Karten zeichnen

Navigations-, POI- und Wetter-Apps, die die folgenden Vorlagen verwenden, können Karten zeichnen, indem sie auf eine Surface zugreifen.

Wenn Sie die folgenden Vorlagen verwenden möchten, muss in Ihrer App eine der entsprechenden Berechtigungen in einem <uses-permission>-Element in der Datei AndroidManifest.xml deklariert werden.

Vorlage Berechtigung Anleitung
NavigationTemplate androidx.car.app.NAVIGATION_TEMPLATES Navigation
MapWithContentTemplate

androidx.car.app.NAVIGATION_TEMPLATES

oder

androidx.car.app.MAP_TEMPLATES

Navigation, POI, Wetter

MapTemplate

(eingestellt)

androidx.car.app.NAVIGATION_TEMPLATES Navigation

PlaceListNavigationTemplate

(eingestellt)

androidx.car.app.NAVIGATION_TEMPLATES Navigation

RoutePreviewNavigationTemplate

(eingestellt)

androidx.car.app.NAVIGATION_TEMPLATES Navigation

Referenzimplementierung ansehen

Eine vollständige Referenzimplementierung finden Sie im Navigationsbeispiel.

Berechtigung für die Oberfläche deklarieren

Zusätzlich zu der für die Vorlage, die Ihre App verwendet, erforderlichen Berechtigung muss Ihre App die Berechtigung androidx.car.app.ACCESS_SURFACE in der Datei AndroidManifest.xml deklarieren, um Zugriff auf die Oberfläche zu erhalten:

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

Auf die Oberfläche zugreifen

Um auf die Surface zuzugreifen, die der Host bereitstellt, müssen Sie eine SurfaceCallback implementieren und diese Implementierung dem AppManager-Autodienst zur Verfügung stellen. Der aktuelle Surface wird an Ihren SurfaceCallback im Parameter SurfaceContainer der Callbacks onSurfaceAvailable() und onSurfaceDestroyed() übergeben.

Kotlin

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

Java

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

Virtuelles Display zum Rendern von Inhalten verwenden

Neben dem direkten Rendern in der Surface mit der Canvas API können Sie Ansichten auch mit den APIs VirtualDisplay und Presentation in der Surface rendern, wie in diesem Beispiel gezeigt:

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 zum Rendern auf dem virtuellen Display verwenden

Sie können eine ComposeView als Inhaltsansicht der Presentation verwenden. Da ComposeView außerhalb einer Aktivität verwendet wird, müssen Sie bestätigen, dass für sie oder eine übergeordnete Ansicht LifecycleOwner und SavedStateRegistryOwner weitergegeben werden. Verwenden Sie dazu setViewTreeLifecycleOwner und setViewTreeSavedStateRegistryOwner.

Session implementiert LifecycleOwner bereits. Um beide Rollen zu bedienen, kann Ihre Implementierung zusätzlich SavedStateRegistryOwner implementieren.

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

  ...
}

Sichtbarer Bereich der Oberfläche

Der Host kann Benutzeroberflächenelemente für die Vorlagen über der Karte zeichnen. Der Host ruft die Methode SurfaceCallback.onVisibleAreaChanged auf, um den Bereich der Oberfläche zu kommunizieren, der am wahrscheinlichsten frei und für den Nutzer sichtbar ist.

Um die Anzahl der Änderungen zu minimieren, ruft der Host die Methode SurfaceCallback.onStableAreaChanged mit dem kleinsten Rechteck auf, das gemäß der aktuellen Vorlage immer sichtbar ist.

Wenn beispielsweise eine Navigations-App die NavigationTemplate mit einem Aktionsstreifen oben verwendet, kann der Aktionsstreifen ausgeblendet werden, wenn der Nutzer nicht mit dem Bildschirm interagiert hat, um mehr Platz auf dem Bildschirm zu schaffen. In diesem Fall wird ein Callback an onStableAreaChanged und onVisibleAreaChanged mit demselben Rechteck gesendet.

Wenn der Aktionsstreifen ausgeblendet ist, wird nur onVisibleAreaChanged mit dem größeren Bereich aufgerufen. Wenn der Nutzer mit dem Bildschirm interagiert, wird onVisibleAreaChanged nur mit dem ersten Rechteck aufgerufen.

Dunkles Design unterstützen

Apps müssen ihre Karte auf der Surface-Instanz mit den richtigen dunklen Farben neu zeichnen, wenn der Host dies aufgrund der Bedingungen erfordert, wie in den Qualitätsrichtlinien für Android-Apps für Autos beschrieben.

Verwenden Sie die Methode CarContext.isDarkMode, um eine dunkle Karte zu zeichnen. Wenn sich der Status des dunklen Designs ändert, erhalten Sie einen Aufruf an Session.onCarConfigurationChanged.

Karten auf dem Clusterdisplay zeichnen

Navigations-Apps können nicht nur Karten auf dem Hauptdisplay zeichnen, sondern auch auf dem Kombiinstrument-Display hinter dem Lenkrad. Weitere Informationen finden Sie unter Auf dem Clusterdisplay zeichnen.