Instrumentencluster-API

Verwenden Sie die Instrument Cluster API (eine Android-API), um Navigations-Apps, einschließlich Google Maps, auf einem sekundären Display in einem Auto anzuzeigen, beispielsweise hinter dem Lenkrad auf der Instrumententafel. Auf dieser Seite wird beschrieben, wie Sie einen Dienst zur Steuerung dieser sekundären Anzeige erstellen und den Dienst dann in CarService integrieren, damit Navigations-Apps eine Benutzeroberfläche anzeigen können.

Terminologie

Auf dieser Seite werden folgende Begriffe verwendet:

Begriff Beschreibung
CarInstrumentClusterManager Eine CarManager Instanz, die es externen Apps ermöglicht, eine Aktivität auf dem Kombiinstrument zu starten und Rückrufe zu empfangen, wenn das Kombiinstrument bereit ist, Aktivitäten anzuzeigen.
CarManager Basisklasse aller Manager, die von externen Apps zur Interaktion mit fahrzeugspezifischen Diensten verwendet werden, die von CarService implementiert werden.
CarService Android-Plattformdienst, der die Kommunikation zwischen externen Apps (einschließlich Google Maps) und fahrzeugspezifischen Funktionen wie dem Zugriff auf das Kombiinstrument ermöglicht.
Ziel Das endgültige Ziel, zu dem das Fahrzeug navigiert.
voraussichtliche Ankunftszeit Geschätzte Ankunftszeit am Zielort.
Haupteinheit (HU) Primäre Recheneinheit, eingebettet in ein Auto. Die HU führt den gesamten Android-Code aus und ist mit dem zentralen Display im Auto verbunden.
Kombiinstrument Sekundäranzeige hinter dem Lenkrad und zwischen den Fahrzeuginstrumenten. Dies kann eine unabhängige Recheneinheit sein, die über das interne Netzwerk des Fahrzeugs (CAN-Bus) mit der HU verbunden ist, oder ein an die HU angeschlossenes sekundäres Display.
InstrumentClusterRenderingService Basisklasse für den Dienst, der als Schnittstelle mit der Anzeige des Kombiinstruments verwendet wird. OEMs müssen eine Erweiterung dieser Klasse bereitstellen, die mit der OEM-spezifischen Hardware interagiert.
KitchenSink-App Test-App im Lieferumfang von Android Automotive enthalten.
Route Ein bestimmter Weg, den ein Fahrzeug entlang navigiert, um an ein Ziel zu gelangen.
Singleton-Dienst Ein Android-Dienst mit dem Attribut android:singleUser . Zu jedem Zeitpunkt läuft höchstens eine Instanz des Dienstes auf dem Android-System.

Voraussetzungen

Um die Integration zu entwickeln, stellen Sie sicher, dass Sie über die folgenden Elemente verfügen:

  • Android-Entwicklungsumgebung. Informationen zum Einrichten der Android-Entwicklungsumgebung finden Sie unter Build-Anforderungen .
  • Laden Sie den Android-Quellcode herunter. Holen Sie sich die neueste Version des Android-Quellcodes vom pi-car-release-Zweig (oder höher) unter https://android.googlesource.com .
  • Haupteinheit (HU). Ein Android-Gerät, auf dem Android 9 (oder höher) ausgeführt werden kann. Dieses Gerät muss über ein eigenes Display verfügen und in der Lage sein, das Display mit neuen Android-Versionen zu flashen.
  • Das Kombiinstrument ist eines der folgenden:
    • Physisches Sekundärdisplay, das an die HU angeschlossen ist. Wenn die Gerätehardware und der Kernel die Verwaltung mehrerer Displays unterstützen.
    • Unabhängige Einheit. Jede über eine Netzwerkverbindung mit der HU verbundene Recheneinheit, die in der Lage ist, einen Videostream zu empfangen und auf einem eigenen Display anzuzeigen.
    • Emulierte Anzeige. Während der Entwicklung können Sie eine dieser emulierten Umgebungen verwenden:
      • Simulierte Sekundäranzeigen. Um eine simulierte sekundäre Anzeige auf einer beliebigen AOSP-Android-Distribution zu aktivieren, gehen Sie zu den Entwickleroptionen-Einstellungen in der System-App „Einstellungen“ und wählen Sie dann „Sekundäre Anzeigen simulieren“ aus. Diese Konfiguration entspricht dem Anschließen eines physischen sekundären Displays, mit der Einschränkung, dass dieses Display über dem primären Display liegt.
      • Emuliertes Kombiinstrument. Der in Android Automotive enthaltene Android-Emulator bietet eine Option zum Anzeigen eines Kombiinstruments mit dem ClusterRenderingService -Dienst, der mit dem sekundären Display verbunden ist.
      • Emulator _qemu-pipes . Der ClusterRenderingService -Dienst ist mit der sekundären Anzeige verbunden. Referenz-Instrumentenkombi-Implementierung zur Verbindung mit diesem emulierten externen Display.

Integrationsarchitektur

Integrationskomponenten

Jede Integration der Instrument Cluster API besteht aus diesen drei Komponenten:

  • CarService
  • Navigations-Apps
  • OEM-Instrumenten-Cluster-Service

Integrationskomponenten

Autowerkstatt

CarService vermittelt zwischen Navigations-Apps und dem Auto und stellt sicher, dass jeweils nur eine Navigations-App aktiv ist und nur Apps mit der Berechtigung android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL Daten an das Auto senden können.

CarService bootet alle fahrzeugspezifischen Dienste und bietet über eine Reihe von Managern Zugriff auf diese Dienste. Um mit den Diensten zu interagieren, können im Auto laufende Apps auf diese Manager zugreifen.

Für die Instrumentencluster-Implementierung müssen Automobil-OEMs eine benutzerdefinierte Implementierung von InstrumentClusterRendererService erstellen und den ClusterRenderingService- Dienst aktualisieren, der mit dem sekundären Display verbunden ist.

Beim Rendern eines Instrumenten-Clusters liest der CarService während des Startvorgangs den InstrumentClusterRendererService Schlüssel des ClusterRenderingService -Dienstes, der mit der sekundären Anzeige verbunden ist. um eine Implementierung von InstrumentClusterService zu finden. In AOSP verweist dieser Eintrag auf den Beispiel-Cluster-Implementierungs-Renderdienst der Navigation State API:

<string name="instrumentClusterRendererService">
android.car.cluster/.ClusterRenderingService
</string>

Der in diesem Eintrag genannte Dienst wird initialisiert und an CarService gebunden. Wenn Navigations-Apps wie Google Maps einen CarInstrumentClusterManager anfordern, stellt CarService einen Manager bereit, der den Instrumenten-Cluster-Status vom gebundenen InstrumentClusterRenderingService aktualisiert. (In diesem Fall bezieht sich „bound“ auf „Android Services “.)

Service für Kombiinstrumente

OEMs müssen ein Android-Paket (APK) erstellen, das eine Unterklasse des ClusterRenderingService -Dienstes enthält und mit der sekundären Anzeige verbunden ist. Der ClusterRenderingService -Dienst ist mit der sekundären Anzeige verbunden. für eine Probe.

Diese Klasse dient zwei Zwecken:

  • Bietet eine Schnittstelle für Android und das Instrumenten-Cluster-Rendering-Gerät (der Zweck dieser Seite).
  • Empfängt und rendert Navigationsstatusaktualisierungen, z. B. detaillierte Navigationsanweisungen.

Für den ersten Zweck müssen OEM-Implementierungen von InstrumentClusterRendererService die sekundäre Anzeige initialisieren, die zum Rendern von Informationen auf Bildschirmen in der Fahrzeugkabine verwendet wird, und diese Informationen an CarService übermitteln, indem sie die Methoden InstrumentClusterRendererService.setClusterActivityOptions() und InstrumentClusterRendererService.setClusterActivityState() aufrufen.

Für die zweite Funktion muss der Instrument Cluster-Dienst eine Implementierung des ClusterRenderingService- Dienstes bereitstellen, die mit der sekundären Anzeige verbunden ist. Schnittstelle, die Navigationsstatusaktualisierungsereignisse empfängt, die als eventType codiert sind, und Ereignisdaten, die in einem Bundle codiert sind.

Integrationssequenz

Das folgende Diagramm veranschaulicht die Implementierung eines Navigationsstatus, der Aktualisierungen rendert:

Integrationssequenz

In dieser Abbildung bedeuten Farben Folgendes:

  • Gelb. CarService und CarNavigationStatusManager werden von der Android-Plattform bereitgestellt. Weitere Informationen finden Sie unter Auto und CAR_NAVIGATION_SERVICE .
  • Cyan. Vom OEM implementierter InstrumentClusterRendererService .
  • Lila. Die von Google und Drittentwicklern implementierte Navigations-App.
  • Grün. CarAppFocusManager . Weitere Informationen finden Sie weiter unten unter „Verwenden der CarAppFocusManager-API“ und unter „CarAppFocusManager“ .

Der Informationsfluss zum Navigationsstatus folgt dieser Reihenfolge:

  1. CarService initialisiert den InstrumentClusterRenderingService .
  2. Während der Initialisierung aktualisiert der InstrumentClusterRenderingService CarService mit:
    1. Anzeigeeigenschaften des Kombiinstruments, z. B. unverdeckte Grenzen (weitere Details zu unverdeckten Grenzen finden Sie später).
    2. Aktivitätsoptionen, die zum Starten von Aktivitäten im Display des Kombiinstruments erforderlich sind (weitere Einzelheiten finden Sie unter Aktivitätsoptionen) .
  3. Eine Navigations-App (z. B. Google Maps für Android Automotive oder eine beliebige Karten-App mit den erforderlichen Berechtigungen):
    1. Ruft einen CarAppFocusManager mithilfe der Car-Klasse von car-lib ab.
    2. Bevor die detaillierten Wegbeschreibungen beginnen, werden CarAppFocusManager.requestFocus() aufgerufen, um CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION als appType Parameter zu übergeben.
  4. CarAppFocusManager übermittelt diese Anfrage an CarService . Bei Genehmigung überprüft CarService das Navigations-App-Paket und findet eine Aktivität, die mit der Kategorie android.car.cluster.NAVIGATION gekennzeichnet ist.
  5. Wenn sie gefunden wird, verwendet die Navigations-App die vom InstrumentClusterRenderingService gemeldeten ActivityOptions , um die Aktivität zu starten, und bezieht die Anzeigeeigenschaften des Kombiinstruments als Extras in die Absicht ein.

Integrieren Sie die API

Die InstrumentClusterRenderingService -Implementierung muss:

  • Lassen Sie sich als Singleton-Dienst kennzeichnen, indem Sie der AndroidManifest.xml den folgenden Wert hinzufügen. Dies ist erforderlich, um sicherzustellen, dass auch während der Initialisierung und des Benutzerwechsels eine einzige Kopie des Instrument Cluster-Dienstes ausgeführt wird:
    android:singleUser="true"
  • Halten Sie die Systemberechtigung BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE . Dies garantiert, dass nur der Instrumenten-Cluster-Rendering-Dienst, der als Teil des Android-Systemabbilds enthalten ist, jemals an den CarService gebunden ist:
    <uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
    

Implementieren Sie InstrumentClusterRenderingService

So erstellen Sie den Dienst:

  1. Schreiben Sie eine Klasse, die den ClusterRenderingService- Dienst erweitert und mit der sekundären Anzeige verbunden ist.
  2. und fügen Sie dann einen entsprechenden Eintrag zu Ihrer AndroidManifest.xml Datei hinzu. Diese Klasse steuert die Anzeige des Kombiinstruments und kann ( optional ) Navigationsstatus-API-Daten rendern.
  3. Verwenden Sie während onCreate() diesen Dienst, um die Kommunikation mit der Rendering-Hardware zu initialisieren. Zu den Optionen gehören:
    • Bestimmen Sie das sekundäre Display, das für das Kombiinstrument verwendet werden soll.
    • Erstellen Sie eine virtuelle Anzeige, damit die Instrumenten-Cluster-App das gerenderte Bild rendert und an eine externe Einheit überträgt (unter Verwendung eines Video-Streaming-Formats wie H.264).
  4. Wenn die oben angegebene Anzeige bereit ist, muss dieser Dienst InstrumentClusterRenderingService#setClusterActivityLaunchOptions() aufrufen, um die genauen ActivityOptions zu definieren, die zum Anzeigen einer Aktivität auf dem Kombiinstrument verwendet werden müssen. Verwenden Sie diese Parameter:
    • Kategorie. Der ClusterRenderingService -Dienst ist mit der sekundären Anzeige verbunden.
    • ActivityOptions. Eine ActivityOptions Instanz, die zum Starten einer Aktivität im Kombiinstrument verwendet werden kann. Zum Beispiel aus der Beispiel-Instrumentencluster-Implementierung auf AOSP:
      getService().setClusterActivityLaunchOptions(
         CATEGORY_NAVIGATION,
         ActivityOptions.makeBasic()
            .setLaunchDisplayId(displayId));
      
  5. Wenn das Kombiinstrument bereit ist, Aktivitäten anzuzeigen, muss dieser Dienst InstrumentClusterRenderingService#setClusterActivityState() aufrufen. Verwenden Sie diese Parameter:
    • Der Dienst „ClusterRenderingService“ category ist mit der sekundären Anzeige verbunden.
    • Das mit dem ClusterRenderingService -Dienst generierte state ist mit der sekundären Anzeige verbunden.
    • Stellen Sie sicher, dass Sie folgende Daten angeben:
      • visible Gibt an, dass das Kombiinstrument sichtbar und bereit zur Anzeige von Inhalten ist.
      • unobscuredBounds Ein Rechteck, das den Bereich innerhalb der Instrumententafel-Anzeige definiert, in dem Inhalte sicher angezeigt werden können. Zum Beispiel Bereiche, die von Zifferblättern und Messgeräten abgedeckt werden.
  6. Überschreiben Sie die Service#dump() Methode und melden Sie Statusinformationen, die für das Debuggen nützlich sind (weitere Informationen finden Sie unter dumpsys ).

Beispielimplementierung von InstrumentClusterRenderingService

Das folgende Beispiel beschreibt eine InstrumentClusterRenderingService -Implementierung, die ein VirtualDisplay erstellt, um den Inhalt des Kombiinstruments auf einem entfernten physischen Display darzustellen.

Alternativ könnte dieser Code die displayId eines physischen sekundären Displays übergeben, das mit der HU verbunden ist, sofern bekannt ist, dass eines verfügbar ist.

/**
* Sample {@link InstrumentClusterRenderingService} implementation
*/
public class SampleClusterServiceImpl extends InstrumentClusterRenderingService {
   // Used to retrieve or create displays
   private final DisplayManager mDisplayManager;
   // Unique identifier for the display to be used for instrument
   // cluster
   private final String mUniqueId = UUID.randomUUID().toString();
   // Format of the instrument cluster display
   private static final int DISPLAY_WIDTH = 1280;
   private static final int DISPLAY_HEIGHT = 720;
   private static final int DISPLAY_DPI = 320;
   // Area not covered by instruments
   private static final int DISPLAY_UNOBSCURED_LEFT = 40;
   private static final int DISPLAY_UNOBSCURED_TOP = 0;
   private static final int DISPLAY_UNOBSCURED_RIGHT = 1200;
   private static final int DISPLAY_UNOBSCURED_BOTTOM = 680;
   @Override
   public void onCreate() {
      super.onCreate();
      // Create a virtual display to render instrument cluster activities on
      mDisplayManager = getSystemService(DisplayManager.class);
      VirtualDisplay display = mDisplayManager.createVirtualDisplay(
          mUniqueId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_DPI, null,
          0 /* flags */, null, null);
      // Do any additional initialization (e.g.: start a video stream
      // based on this virtual display to present activities on a remote
      // display).
      onDisplayReady(display.getDisplay());
}
private void onDisplayReady(Display display) {
    // Report activity options that should be used to launch activities on
    // the instrument cluster.
    String category = CarInstrumentClusterManager.CATEGORY_NAVIGATION;
    ActionOptions options = ActivityOptions.makeBasic()
        .setLaunchDisplayId(display.getDisplayId());
    setClusterActivityOptions(category, options);
    // Report instrument cluster state.
    Rect unobscuredBounds = new Rect(DISPLAY_UNOBSCURED_LEFT,
        DISPLAY_UNOBSCURED_TOP, DISPLAY_UNOBSCURED_RIGHT,
        DISPLAY_UNOBSCURED_BOTTOM);
    boolean visible = true;
    ClusterActivityState state = ClusterActivityState.create(visible,
       unobscuredBounds);
    setClusterActivityState(category, options);
  }
}

Verwenden Sie die CarAppFocusManager-API

Die CarAppFocusManager-API stellt eine Methode namens getAppTypeOwner() bereit, mit der der von OEMs geschriebene Clusterdienst erkennen kann, welche Navigations-App zu einem bestimmten Zeitpunkt den Navigationsfokus hat. OEMs können die vorhandene Methode CarAppFocusManager#addFocusListener() verwenden und dann getAppTypeOwner() verwenden, um zu erfahren, welche App den Fokus hat. Mit diesen Informationen können OEMs:

  • Schalten Sie die im Cluster angezeigte Aktivität auf die Clusteraktivität um, die von der Navigations-App bereitgestellt wird, die den Fokus hält.
  • Kann erkennen, ob die fokussierte Navigations-App eine Clusteraktivität aufweist oder nicht. Wenn die fokussierte Navigations-App keine Cluster-Aktivität aufweist (oder wenn eine solche Aktivität deaktiviert ist), können OEMs dieses Signal an das Fahrzeug-DIM senden, sodass die Navigationsfacette des Clusters vollständig übersprungen wird.

Verwenden Sie CarAppFocusManager um den aktuellen App-Fokus festzulegen und darauf zu warten, z. B. eine aktive Navigation oder einen Sprachbefehl. Normalerweise wird nur eine Instanz einer solchen App im System aktiv ausgeführt (oder ist darauf fokussiert).

Verwenden Sie die Methode CarAppFocusManager#addFocusListener(..) , um auf Änderungen des App-Fokus zu warten:

import android.car.CarAppFocusManager;

...

Car car = Car.createCar(this);
mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE);
mAppFocusManager.addFocusListener(this, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);

...

public void onAppFocusChanged(int appType, boolean active) {
    // Use the CarAppFocusManager#getAppTypeOwner(appType) method call
    // to retrieve a list of active package names
}

Verwenden Sie die Methode CarAppFocusManager#getAppTypeOwner(..) , um die Paketnamen des aktuellen Besitzers eines bestimmten App-Typs abzurufen, der im Fokus ist. Diese Methode gibt möglicherweise mehr als einen Paketnamen zurück, wenn der aktuelle Besitzer die Funktion android:sharedUserId verwendet.

import android.car.CarAppFocusManager;

...

Car car = Car.createCar(this);
mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE);
List<String> focusOwnerPackageNames = mAppFocusManager.getAppTypeOwner(
              CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);

if (focusOwnerPackageNames == null || focusOwnerPackageNames.isEmpty()) {
        // No Navigation app has focus
        // OEM may choose to show their default cluster view
} else {
       // focusOwnerPackageNames
       // Use the PackageManager to retrieve the cluster activity for the package(s)
       // returned in focusOwnerPackageNames
}

...

Anhang: Verwenden Sie die Beispiel-App

AOSP stellt eine Beispiel-App bereit, die die Navigation State API implementiert.

So führen Sie diese Beispiel-App aus:

  1. Erstellen und flashen Sie Android Auto auf einer unterstützten HU. Verwenden Sie die für Ihr Gerät spezifischen Android-Bau- und Flash-Anweisungen. Anweisungen finden Sie unter Verwenden von Referenztafeln .
  2. Schließen Sie ein physisches sekundäres Display an die HU an (falls unterstützt) oder schalten Sie die virtuelle sekundäre HU ein:
    1. Wählen Sie in der App „Einstellungen“ den Entwicklermodus aus.
    2. Gehen Sie zu Einstellungen > System > Erweitert > Entwickleroptionen > Sekundäranzeigen simulieren .
  3. Starten Sie die HU neu. Der ClusterRenderingService -Dienst ist mit der sekundären Anzeige verbunden.
  4. So starten Sie die KitchenSink-App:
    1. Öffne die Schublade.
    2. Gehen Sie zu Inst. Cluster .
    3. Klicken Sie auf Metadaten starten .

KitchenSink fordert den NAVIGATION-Fokus an, der den DirectRenderingCluster Dienst anweist, eine simulierte Benutzeroberfläche auf dem Kombiinstrument anzuzeigen.