API Instrument Cluster

Usa l'API Instrument Cluster (un'API Android) per visualizzare le app di navigazione, compreso Google Maps, su un display secondario di un'auto, come dietro al sul volante sul cruscotto. In questa pagina viene descritto come creare un per controllare il display secondario e integrare il servizio CarService in modo che le app di navigazione possano visualizzare a riga di comando.

Terminologia

In questa pagina vengono utilizzati i termini che seguono.

GestoreclusterCarInstrument
Un'istanza di CarManager che consente alle app esterne di avviare un'attività su il quadro strumenti e riceve i callback quando il quadro strumenti è pronto per essere visualizzato attività.
Gestore auto
Classe di base di tutti i gestori utilizzati dalle app esterne per interagire con le specifiche dell'auto e servizi aggiuntivi implementati da CarService.
CarService
Servizio della piattaforma Android che consente la comunicazione tra app esterne (incluso Google Maps) e funzionalità specifiche dell'auto, come l'accesso al quadro strumenti.
Destinazione
La destinazione finale a cui si dirigerà il veicolo.
Orario di arrivo stimato
L'orario di arrivo stimato a una destinazione.
Unità principale (HU)
Unità di calcolo principale incorporata in un'auto. L'HU esegue tutto il codice Android collegata al display centrale dell'auto.
Quadro strumenti
Display secondario posizionato dietro al volante e tra l'auto i modelli di machine learning. Può trattarsi di un'unità di calcolo indipendente collegata HU attraverso la rete interna dell'auto (bus CAN) o un display secondario collegati all'HU.
InstrumentClusterRenderingService
Classe base per il servizio utilizzato per interfacciarsi con il cluster di strumenti display. Gli OEM devono fornire un'estensione di questa classe che interagisca con l'hardware specifico dell'OEM.
App KitchenSink
App di test inclusa in Android Automotive.
Itinerario
Un percorso specifico lungo il quale un veicolo procede per arrivare a una destinazione.
Servizio Singleton
Un servizio Android con l'attributo android:singleUser. Alle ore in un determinato momento, al massimo un'istanza del servizio viene eseguita sul sistema Android.

Prerequisiti

Prima di continuare, assicurati di avere questi elementi:

  • Ambiente di sviluppo Android. Per configurare Android per l'ambiente di sviluppo, consulta Requisiti di build.
  • Scarica il codice sorgente di Android. Scarica l'ultima versione di il codice sorgente Android dal ramo pi-car-release (o successivo) all'indirizzo https://android.googlesource.com.
  • Unità principale (HU). Un dispositivo Android in grado di eseguire Android 9 (o versioni successive). Questo dispositivo deve avere un proprio display ed essere in grado di: far lampeggiare il display con nuove build di Android.
  • Il cluster degli strumenti è uno dei seguenti:
      .
    • Display fisico secondario collegato all'HU. Se l'hardware e il kernel del dispositivo supportano la gestione di più display.
    • Unità indipendente. Qualsiasi unità di calcolo collegata HU tramite una connessione di rete, in grado di ricevere e visualizzare uno stream video sul proprio display.
    • Display emulato. Durante lo sviluppo, puoi utilizzare uno dei seguenti questi ambienti emulati:
      • Display secondari simulati. Per attivare una simulazione display secondario su qualsiasi distribuzione Android AOSP, vai alle Opzioni sviluppatore nell'app di sistema Impostazioni, quindi seleziona Simula secondaria display Questa configurazione equivale al collegamento di un indirizzo fisico secondario display, con la limitazione che è sovrapposto a quello principale display.
      • Quadro strumentale emulato. L'emulatore Android incluso con AAOS offre la possibilità di visualizzare un quadro strumentale con ClusterRenderingService.

Architettura di integrazione

Componenti di integrazione

Qualsiasi integrazione dell'API Instrument Cluster è costituita da questi tre componenti:

  • CarService
  • App di navigazione
  • Servizio cluster strumentazione OEM

Componenti di integrazione

CarService

CarService agisce da mediatore tra le app di navigazione e l'auto, garantendo che vengano sia attiva un'app di navigazione alla volta e soltanto le app con L'autorizzazione android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL può inviare dati all'auto.

CarService esegue il bootstrap di tutti i servizi specifici dell'auto e fornisce l'accesso a questi servizi tramite una serie di gestori. Per interagire con i servizi, le app in esecuzione nell'auto possono accedere a questi gestori.

Per l'implementazione del quadro strumenti, gli OEM del settore auto e motori devono creare una di InstrumentClusterRendererService e aggiornare ClusterRenderingService.

Durante il rendering di un cluster di strumenti, durante il processo di avvio, CarService legge la chiave InstrumentClusterRendererService del ClusterRenderingService per individuare un'implementazione di InstrumentClusterService. In AOSP, questa voce punta al servizio di rendering dell'implementazione del cluster di esempio dell'API Navigation State:

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

Il servizio a cui si fa riferimento in questa voce è inizializzato e associato a CarService. Quando le app di navigazione, come Google Maps, richiedono CarInstrumentClusterManager, CarService offre un gestore aggiorna lo stato del cluster degli strumenti dal limite InstrumentClusterRenderingService. In questo caso, bound si riferisce a Android servizi.)

Servizio cluster di strumenti

Gli OEM devono creare un pacchetto Android (APK) contenente una sottoclasse ClusterRenderingService.

Questa lezione ha due scopi:

  • Fornisce un'interfaccia Android e il dispositivo di rendering del cluster degli strumenti (scopo di questa pagina).
  • Riceve ed esegue il rendering degli aggiornamenti sullo stato della navigazione, ad esempio le istruzioni passo passo indicazioni stradali.

Al primo scopo, le implementazioni OEM di InstrumentClusterRendererService Deve inizializzare il display secondario utilizzato per visualizzare le informazioni sugli schermi dell'abitacolo e comunicare queste informazioni a CarService chiamando il InstrumentClusterRendererService.setClusterActivityOptions() e InstrumentClusterRendererService.setClusterActivityState() metodi.

Per la seconda funzione, il servizio Cluster degli strumenti deve fornire una dell'implementazione ClusterRenderingService che riceve eventi di aggiornamento dello stato della navigazione, codificati come eventType e dati sugli eventi codificati in un bundle.

Sequenza di integrazione

Il seguente diagramma illustra l'implementazione di uno stato di navigazione che esegue il rendering degli aggiornamenti:

Sequenza di integrazione

In questa illustrazione, i colori indicano quanto segue:

  • Giallo. CarService e CarNavigationStatusManager forniti dalla piattaforma Android. Per saperne di più, vedi Auto e CAR_NAVIGATION_SERVICE.
  • Ciano InstrumentClusterRendererService implementato dall'OEM.
  • Viola. App di navigazione implementata da Google e da terze parti sviluppatori.
  • Verde. CarAppFocusManager. Per saperne di più, vedi Utilizzo dell'API CarAppFocusManager sotto e CarAppFocusManager.

Il flusso di informazioni sullo stato della navigazione segue questa sequenza:

  1. CarService inizializza InstrumentClusterRenderingService.
  2. Durante l'inizializzazione, InstrumentClusterRenderingService si aggiorna CarService con:
      .
    1. Proprietà di visualizzazione del quadro strumenti, come confini netti (scopri di più sui confini non chiari più avanti).
    2. Opzioni di attività necessarie per avviare attività all'interno del display del quadro strumenti. Per saperne di più, vedi ActivityOptions.
  3. Un'app di navigazione (come Google Maps per Android Automotive o qualsiasi app per le mappe con le autorizzazioni richieste):
    1. Ottieni un CarAppFocusManager utilizzando la classe Car di car-lib.
    2. Prima dell'inizio delle indicazioni stradali passo passo, le chiamate a CarAppFocusManager.requestFocus() per superare CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION come appType .
  4. CarAppFocusManager comunica questa richiesta a CarService. Se concesso, CarService ispeziona il pacchetto dell'app di navigazione e individua un attività contrassegnata con categoria android.car.cluster.NAVIGATION.
  5. Se lo trovi, l'app di navigazione utilizza il ActivityOptions segnalato dal InstrumentClusterRenderingService per avviare l'attività e include Il cluster degli strumenti mostra le proprietà come extra nell'intent.

Integra l'API

L'implementazione InstrumentClusterRenderingService deve:

  • Essere designato come servizio singleton aggiungendo il seguente valore a il file AndroidManifest.xml. Questa operazione è necessaria per garantire che una singola copia del Il servizio Instrument Cluster viene eseguito, anche durante l'inizializzazione e il cambio di utente:
    android:singleUser="true"
  • Mantieni l'autorizzazione di sistema BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE. Questo garantisce che solo il servizio di rendering di Instrument Cluster incluso come parte dell'immagine di sistema Android è mai vincolata dall'CarService:
    <uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
    

Implementare InstrumentClusterRenderingService

Per creare il servizio:

  1. Scrivi una classe che si estenda a ClusterRenderingService quindi aggiungi una voce corrispondente al tuo file AndroidManifest.xml. Questo corso controlla la visualizzazione del quadro strumenti e può (facoltativamente) visualizzare lo stato di navigazione dati dell'API.
  2. Durante onCreate(), utilizza questo servizio per inizializzare la comunicazione con l'hardware di rendering. Le opzioni disponibili sono le seguenti:
    • Determina il display secondario da utilizzare per il quadro strumenti.
    • Crea un display virtuale in modo che l'app Cluster strumenti esegua il rendering e trasmetta il codice eseguito il rendering dell'immagine a un'unità esterna (utilizzando un formato di streaming video, come H.264).
  3. Quando il display sopra indicato è pronto, il servizio deve chiamare InstrumentClusterRenderingService#setClusterActivityLaunchOptions() per definire l'esatto ActivityOptions che deve essere utilizzato per visualizzare un'attività nella Cluster degli strumenti. Utilizza questi parametri:
    • category. ClusterRenderingService.
    • ActivityOptions. Un'istanza ActivityOptions che può essere utilizzata per avviare un'attività nel cluster degli strumenti. Ad esempio, Implementazione di Instrument Cluster su AOSP:
      getService().setClusterActivityLaunchOptions(
        CATEGORY_NAVIGATION,
        ActivityOptions.makeBasic()
            .setLaunchDisplayId(displayId));
      
  4. Quando il cluster degli strumenti è pronto per visualizzare le attività, questo servizio deve richiamare InstrumentClusterRenderingService#setClusterActivityState(). Utilizza questi parametri:
    • category ClusterRenderingService.
    • state bundle generato con ClusterRenderingService. Assicurati di fornire questi dati:
      • visible Specifica il cluster degli strumenti come visibile e pronto per visualizzare i contenuti.
      • unobscuredBounds Un rettangolo che definisce l'area all'interno di Display del quadro strumenti in cui è possibile visualizzare i contenuti in sicurezza. Ad esempio, le aree coperti da quadranti e indicatori.
  5. Esegui l'override del metodo Service#dump() e delle informazioni sullo stato del report utili per debug (vedi dumpsys per ulteriori informazioni).

Esempio di implementazione di InstrumentClusterRenderingService

L'esempio seguente illustra un InstrumentClusterRenderingService l'implementazione, che crea un VirtualDisplay per presentare lo strumento Raggruppare i contenuti su un display fisico remoto.

In alternativa, questo codice potrebbe passare il displayId di un secondario fisico collegato all'HU, se noto che è disponibile.

/**
* 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);
  }
}

Utilizza l'API CarAppFocusManager

L'API CarAppFocusManager fornisce un metodo denominato getAppTypeOwner(), che consente il servizio cluster scritto dagli OEM per sapere quale app di navigazione è incentrata sulla navigazione nel tempo. Gli OEM possono usare il metodo CarAppFocusManager#addFocusListener() esistente. poi usa getAppTypeOwner() per scoprire quale app è incentrata su di essi. Con queste informazioni, Gli OEM possono:

  • Cambia l'attività mostrata nel cluster all'attività del cluster fornita dall'app di navigazione. mantenendo lo stato attivo.
  • Può rilevare se l'app di navigazione con lo stato attivo ha un'attività cluster o meno. Se lo stato attivo l'app di navigazione non ha un'attività cluster (o se questa attività è disabilitata), gli OEM possono inviare questo segnale al DIM dell'auto in modo che il facet di navigazione del cluster venga ignorato del tutto.

Usa CarAppFocusManager per impostare e ascoltare l'attuale focus dell'app, ad esempio la navigazione attiva o un comando vocale. Di solito, solo un'istanza di un'app di questo tipo è attiva in esecuzione (o attivo) nel sistema.

Usa il metodo CarAppFocusManager#addFocusListener(..) per ascoltare lo stato attivo delle app modifiche:

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
}

Usa il metodo CarAppFocusManager#getAppTypeOwner(..) per recuperare il pacchetto Nomi dell'attuale proprietario di un determinato tipo di app attivo. Questo metodo può restituire più di un nome di pacchetto se il proprietario corrente utilizza la funzionalità android:sharedUserId.

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
}

...

Appendice: utilizzo dell'app di esempio

AOSP fornisce un'app di esempio che implementa l'API Navigation State.

Per eseguire questa app di esempio:

  1. Crea e esegui il flashing di Android Auto su un HU supportato. Utilizza la Istruzioni per la creazione e il flashing di Android specifiche per il tuo dispositivo. Per istruzioni, vedi Utilizzo delle schede di riferimento.
  2. Collega un display fisico secondario a HU (se supportato) o attiva il HU secondaria:
    1. Seleziona Modalità sviluppatore nell'app Impostazioni.
    2. Vai a Impostazioni > Sistema > Avanzate > Opzioni sviluppatore > Simula display secondari.
  3. Riavvia l'HU
  4. Per avviare l'app KitchenSink:
    1. Apri il riquadro a scomparsa.
    2. Vai alla pagina Impostazioni Google Cloud.
    3. Fai clic su AVVIA METADATI.

KitchenSink richiede lo stato attivo di NAVIGATION, che indica all'DirectRenderingCluster per visualizzare una simulazione dell'interfaccia utente sul cluster degli strumenti.