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.
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à.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
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:
In questa illustrazione, i colori indicano quanto segue:
- Giallo.
CarService
eCarNavigationStatusManager
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:
CarService
inizializzaInstrumentClusterRenderingService
.- Durante l'inizializzazione,
InstrumentClusterRenderingService
si aggiornaCarService
con:- .
- Proprietà di visualizzazione del quadro strumenti, come confini netti (scopri di più sui confini non chiari più avanti).
- Opzioni di attività necessarie per avviare attività all'interno del display del quadro strumenti. Per saperne di più, vedi ActivityOptions.
- Un'app di navigazione (come Google Maps per Android Automotive o qualsiasi app per le mappe
con le autorizzazioni richieste):
- Ottieni un
CarAppFocusManager
utilizzando la classe Car di car-lib. - Prima dell'inizio delle indicazioni stradali passo passo, le chiamate a
CarAppFocusManager.requestFocus()
per superareCarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION
comeappType
.
- Ottieni un
CarAppFocusManager
comunica questa richiesta aCarService
. Se concesso,CarService
ispeziona il pacchetto dell'app di navigazione e individua un attività contrassegnata con categoriaandroid.car.cluster.NAVIGATION
.- Se lo trovi, l'app di navigazione utilizza il
ActivityOptions
segnalato dalInstrumentClusterRenderingService
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:
- 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. - 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).
- Quando il display sopra indicato è pronto, il servizio deve chiamare
InstrumentClusterRenderingService#setClusterActivityLaunchOptions()
per definire l'esattoActivityOptions
che deve essere utilizzato per visualizzare un'attività nella Cluster degli strumenti. Utilizza questi parametri:category.
ClusterRenderingService.ActivityOptions.
Un'istanzaActivityOptions
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));
- 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.
- 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:
- 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.
- Collega un display fisico secondario a HU (se supportato) o attiva il
HU secondaria:
- Seleziona Modalità sviluppatore nell'app Impostazioni.
- Vai a Impostazioni > Sistema > Avanzate > Opzioni sviluppatore > Simula display secondari.
- Riavvia l'HU
- Per avviare l'app KitchenSink:
- Apri il riquadro a scomparsa.
- Vai alla pagina Impostazioni Google Cloud.
- 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.