La libreria di app Android for Cars ti consente di portare in auto le tue app di navigazione, punti d'interesse (POI), Internet of Things (IoT) o meteo. A questo scopo, fornisce un insieme di modelli progettati per soddisfare gli standard di distrazione del conducente e si occupa di dettagli come la varietà di fattori dello schermo dell'auto e delle modalità di input.
Questa guida fornisce una panoramica delle funzionalità e dei concetti chiave della libreria e ti accompagna nella procedura di configurazione di un'app di base.
Prima di iniziare
- Consulta le pagine Progettazione per la guida
che trattano la libreria di app per auto
- Panoramiche delle categorie app di navigazione e altre app correlate alla guida
- Panoramica di Crea app con i modelli
- Elementi costitutivi che coprono Modelli e Componenti dei modelli
- Flussi di esempio che mostrano pattern UX comuni
- Requisiti delle app basate su modelli
- Esamina i termini e i concetti chiave nella sezione seguente.
- Acquisisci familiarità con l'interfaccia utente del sistema Android Auto e con il design di Android Automotive OS.
- Consulta le note di rilascio.
- Esamina gli esempi.
Termini e concetti chiave
- Modelli e modelli
- L'interfaccia utente è rappresentata da un grafico di oggetti modello che possono essere disposti insieme in modi diversi, come consentito dal modello a cui appartengono. I modelli sono un sottoinsieme dei modelli che possono fungere da radice in questi grafici. I modelli includono le informazioni da mostrare all'utente sotto forma di testo e immagini, nonché gli attributi per configurare gli aspetti dell'aspetto visivo di queste informazioni, ad esempio i colori del testo o le dimensioni delle immagini. L'host converte i modelli in visualizzazioni progettate per soddisfare gli standard di distrazione del conducente e si occupa di dettagli come la varietà di fattori dello schermo dell'auto e delle modalità di input.
- Host
- L'host è il componente backend che implementa la funzionalità offerta dalle API della libreria in modo che la tua app possa essere eseguita nell'auto. Le responsabilità dell'host vanno dalla scoperta dell'app e dalla gestione del suo ciclo di vita alla conversione dei modelli in visualizzazioni e alla notifica all'app delle interazioni degli utenti. Sui dispositivi mobili, questo host viene implementato da Android Auto. Su Android Automotive OS, questo host viene installato come app di sistema.
- Limitazioni dei modelli
- Modelli diversi impongono restrizioni nel contenuto dei modelli. Ad esempio, i modelli di elenchi hanno limiti al numero di elementi che possono essere presentati all'utente. I modelli hanno anche limitazioni nel modo in cui possono essere collegati per formare il flusso di un'attività. Ad esempio, l'app può inviare fino a cinque modelli allo stack di schermate. Per ulteriori dettagli, consulta la sezione Limitazioni dei modelli.
Screen
Screen
è una classe fornita dalla libreria che le app implementano per gestire l'interfaccia utente presentata all'utente. UnScreen
ha un ciclo di vita e fornisce il meccanismo per l'app per inviare il modello da visualizzare quando lo schermo è visibile. Le istanzeScreen
possono anche essere inserite e rimosse da uno stackScreen
, il che garantisce che rispettino le limitazioni del flusso del modello.CarAppService
CarAppService
è una classe astrattaService
che la tua app deve implementare ed esportare per essere rilevata e gestita dall'host. IlCarAppService
della tua app è responsabile della convalida dell'attendibilità di una connessione host utilizzandocreateHostValidator
e successivamente fornisce istanzeSession
per ogni connessione utilizzandoonCreateSession
.Session
Session
è una classe astratta che la tua app deve implementare e restituire utilizzandoCarAppService.onCreateSession
. Funge da punto di accesso per visualizzare le informazioni sullo schermo dell'auto. Ha un ciclo di vita che indica lo stato attuale dell'app sullo schermo dell'auto, ad esempio quando l'app è visibile o nascosta.Quando viene avviato un
Session
, ad esempio all'avvio dell'app, l'host richiede la visualizzazione delScreen
iniziale utilizzando il metodoonCreateScreen
.
Installare la libreria di app per auto
Consulta la pagina di rilascio della libreria Jetpack per istruzioni su come aggiungere la libreria alla tua app.
Configurare i file manifest dell'app
Prima di poter creare l'app per l'auto, configura i file manifest dell'app come segue.
Dichiarare CarAppService
L'host si connette alla tua app tramite l'implementazione di
CarAppService
. Devi
dichiarare questo servizio nel manifest per consentire all'host di scoprire e connettersi
alla tua app.
Devi anche dichiarare la categoria dell'app nell'elemento
<category>
del filtro per intent
dell'app. Consulta l'elenco delle
categorie di app supportate per i valori consentiti per
questo elemento.
Il seguente snippet di codice mostra come dichiarare un servizio di app per auto per un'app di punti di interesse nel file manifest:
<application>
...
<service
...
android:name=".MyCarAppService"
android:exported="true">
<intent-filter>
<action android:name="androidx.car.app.CarAppService"/>
<category android:name="androidx.car.app.category.POI"/>
</intent-filter>
</service>
...
<application>
Categorie di app supportate
Dichiara la categoria della tua app aggiungendo uno o più dei seguenti valori di categoria
nel filtro per intent quando dichiari il tuo CarAppService
come descritto
nella sezione precedente:
androidx.car.app.category.NAVIGATION
: un'app che fornisce indicazioni stradali passo passo. Consulta Creare app di navigazione per le auto.androidx.car.app.category.POI
: un'app che fornisce funzionalità pertinenti per trovare punti di interesse come parcheggi, stazioni di ricarica e stazioni di servizio. Consulta Creare app per punti di interesse per le auto.androidx.car.app.category.IOT
: un'app che consente agli utenti di intraprendere azioni pertinenti sui dispositivi connessi dall'interno dell'auto. Vedi Creare app per l'internet delle cose per le auto.androidx.car.app.category.WEATHER
: un'app che consente agli utenti di visualizzare informazioni meteo pertinenti relative alla loro posizione attuale o lungo il percorso. Vedi Creare app meteo per le auto.androidx.car.app.category.MEDIA
: un'app che consente agli utenti di sfogliare e riprodurre musica, radio, audiolibri e altri contenuti audio in auto. Vedi Creare app multimediali basate su modelli per le auto.androidx.car.app.category.MESSAGING
: un'app che consente agli utenti di comunicare utilizzando messaggi di testo brevi. Vedi Creare esperienze di messaggistica basate su modelli per Android Auto.androidx.car.app.category.CALLING
: un'app che consente agli utenti di comunicare tramite chiamate vocali. Consulta Crea esperienze di chiamata per Android Auto.
Consulta l'articolo Qualità delle app per Android per le auto per descrizioni dettagliate di ogni categoria e dei criteri per l'appartenenza.
Specifica il nome e l'icona dell'app
Devi specificare un nome e un'icona dell'app che l'host può utilizzare per rappresentare la tua app nell'interfaccia utente di sistema.
Puoi specificare il nome e l'icona dell'app utilizzati per rappresentare la tua app utilizzando gli attributi label
e icon
di CarAppService
:
...
<service
android:name=".MyCarAppService"
android:exported="true"
android:label="@string/my_app_name"
android:icon="@drawable/my_app_icon">
...
</service>
...
Se l'etichetta o l'icona non sono dichiarate nell'elemento
<service>
, l'host
utilizza i valori specificati per l'elemento
<application>
.
Impostare un tema personalizzato
Per impostare un tema personalizzato per l'app per l'auto, aggiungi un elemento
<meta-data>
nel file
manifest, come segue:
<meta-data android:name="androidx.car.app.theme" android:resource="@style/MyCarAppTheme />
Dopodiché, dichiara la risorsa di stile per impostare i seguenti attributi per il tema personalizzato dell'app per auto:
<resources> <style name="MyCarAppTheme"> <item name="carColorPrimary">@layout/my_primary_car_color</item> <item name="carColorPrimaryDark">@layout/my_primary_dark_car_color</item> <item name="carColorSecondary">@layout/my_secondary_car_color</item> <item name="carColorSecondaryDark">@layout/my_secondary_dark_car_color</item> <item name="carPermissionActivityLayout">@layout/my_custom_background</item> </style> </resources>
Livello API Car App
La libreria di app per auto definisce i propri livelli API in modo che tu possa sapere quali funzionalità della libreria sono supportate dall'host del modello su un veicolo.
Per recuperare il livello API Car App più elevato supportato da un host, utilizza il metodo
getCarAppApiLevel()
.
Dichiara il livello API Car App minimo supportato dalla tua app nel file
AndroidManifest.xml
:
<manifest ...>
<application ...>
<meta-data
android:name="androidx.car.app.minCarApiLevel"
android:value="1"/>
</application>
</manifest>
Consulta la documentazione relativa all'annotazione
RequiresCarApi
per informazioni dettagliate su come mantenere la compatibilità con le versioni precedenti e dichiarare
il livello API minimo richiesto per utilizzare una funzionalità. Per una definizione del livello API richiesto per utilizzare una determinata funzionalità della libreria di app per auto, consulta la documentazione di riferimento per CarAppApiLevels
.
Crea CarAppService e Session
La tua app deve estendere la classe
CarAppService
e implementare
il suo metodo
onCreateSession
, che restituisce un'istanza
Session
corrispondente alla connessione corrente all'host:
Kotlin
class HelloWorldService : CarAppService() { ... override fun onCreateSession(): Session { return HelloWorldSession() } ... }
Java
public final class HelloWorldService extends CarAppService { ... @Override @NonNull public Session onCreateSession() { return new HelloWorldSession(); } ... }
L'istanza Session
è responsabile della restituzione dell'istanza Screen
da utilizzare al primo avvio dell'app:
Kotlin
class HelloWorldSession : Session() { ... override fun onCreateScreen(intent: Intent): Screen { return HelloWorldScreen(carContext) } ... }
Java
public final class HelloWorldSession extends Session { ... @Override @NonNull public Screen onCreateScreen(@NonNull Intent intent) { return new HelloWorldScreen(getCarContext()); } ... }
Per gestire scenari in cui l'app per l'auto deve iniziare da una schermata diversa
dalla schermata Home o di destinazione dell'app, ad esempio la gestione dei link diretti, puoi
precompilare una cronologia delle schermate utilizzando
ScreenManager.push
prima di tornare da
onCreateScreen
.
Il pre-seeding consente agli utenti di tornare alle schermate precedenti dalla prima
schermata mostrata dall'app.
Creare la schermata iniziale
Crea le schermate visualizzate dalla tua app definendo classi che estendono la classe
Screen
e implementando il relativo metodo
onGetTemplate
, che restituisce l'istanza
Template
che rappresenta
lo stato della UI da visualizzare sullo schermo dell'auto.
Il seguente snippet mostra come dichiarare un Screen
che utilizza un modello PaneTemplate
per visualizzare una semplice stringa "Hello world!":
Kotlin
class HelloWorldScreen(carContext: CarContext) : Screen(carContext) { override fun onGetTemplate(): Template { val row = Row.Builder().setTitle("Hello world!").build() val pane = Pane.Builder().addRow(row).build() return PaneTemplate.Builder(pane) .setHeaderAction(Action.APP_ICON) .build() } }
Java
public class HelloWorldScreen extends Screen { @NonNull @Override public Template onGetTemplate() { Row row = new Row.Builder().setTitle("Hello world!").build(); Pane pane = new Pane.Builder().addRow(row).build(); return new PaneTemplate.Builder(pane) .setHeaderAction(Action.APP_ICON) .build(); } }
La classe CarContext
La classe CarContext
è una sottoclasse ContextWrapper
accessibile alle tue istanze Session
e Screen
. Fornisce l'accesso
ai servizi auto, come
ScreenManager
per la gestione dello
stack di schermate; l'AppManager
per la funzionalità generale
relativa alle app, come l'accesso all'oggetto Surface
per disegnare mappe; e l'NavigationManager
utilizzato dalle app di navigazione passo passo per comunicare i metadati di navigazione e altri eventi correlati alla navigazione con l'host.
Consulta Accedere ai modelli di navigazione per un elenco completo delle funzionalità della libreria disponibili per le app di navigazione.
CarContext
offre anche altre
funzionalità, ad esempio la possibilità di caricare risorse disegnabili utilizzando la configurazione
dallo schermo dell'auto, avviare un'app in auto utilizzando gli intent
e segnalare se l'app deve visualizzare la mappa nel tema scuro.
Implementare la navigazione sullo schermo
Le app spesso presentano diverse schermate, ognuna delle quali potrebbe utilizzare modelli diversi in cui l'utente può navigare mentre interagisce con l'interfaccia visualizzata nella schermata.
La classe ScreenManager
fornisce
uno stack di schermate che puoi utilizzare per inserire schermate che possono essere rimosse automaticamente
quando l'utente seleziona un pulsante Indietro sullo schermo dell'auto o utilizza il pulsante Indietro hardware
disponibile in alcune auto.
Il seguente snippet mostra come aggiungere un'azione Indietro a un modello di messaggio, nonché un'azione che visualizza una nuova schermata quando viene selezionata dall'utente:
Kotlin
val template = MessageTemplate.Builder("Hello world!") .setHeaderAction(Action.BACK) .addAction( Action.Builder() .setTitle("Next screen") .setOnClickListener { screenManager.push(NextScreen(carContext)) } .build()) .build()
Java
MessageTemplate template = new MessageTemplate.Builder("Hello world!") .setHeaderAction(Action.BACK) .addAction( new Action.Builder() .setTitle("Next screen") .setOnClickListener( () -> getScreenManager().push(new NextScreen(getCarContext()))) .build()) .build();
L'oggetto Action.BACK
è un
Action
standard che richiama
automaticamente ScreenManager.pop
.
Questo comportamento può essere sostituito utilizzando l'istanza
OnBackPressedDispatcher
disponibile da
CarContext
.
Per garantire che l'app sia sicura da usare durante la guida, lo stack di schermate può avere una profondità massima di cinque schermate. Per ulteriori dettagli, consulta la sezione Limitazioni dei modelli.
Aggiornare i contenuti di un modello
La tua app può richiedere l'invalidazione dei contenuti di un
Screen
chiamando il metodo
Screen.invalidate
.
L'host richiama successivamente il metodo
Screen.onGetTemplate
della tua app per recuperare il modello con i nuovi contenuti.
Quando aggiorni un Screen
, è
importante comprendere i contenuti specifici del modello che possono essere aggiornati
in modo che l'host non conteggi il nuovo modello ai fini della quota.
Per ulteriori dettagli, consulta la sezione Limitazioni dei modelli.
Ti consigliamo di strutturare le schermate in modo che esista una mappatura
uno a uno tra un Screen
e il tipo di
modello restituito tramite l'implementazione di onGetTemplate
.
Disegnare mappe
Le app di navigazione, per punti d'interesse (PDI) e meteo che utilizzano i seguenti modelli possono disegnare mappe accedendo a un Surface
.
Per utilizzare i seguenti modelli, l'app deve avere una delle autorizzazioni corrispondenti dichiarate in un elemento <uses-permission>
nel file AndroidManifest.xml
.
Modello | Autorizzazione modello | Indicazioni per le categorie |
---|---|---|
NavigationTemplate |
androidx.car.app.NAVIGATION_TEMPLATES |
Navigazione |
MapWithContentTemplate |
androidx.car.app.NAVIGATION_TEMPLATES OPPURE androidx.car.app.MAP_TEMPLATES |
Navigazione, PDI, Meteo |
MapTemplate (ritirato) |
androidx.car.app.NAVIGATION_TEMPLATES |
Navigazione |
PlaceListNavigationTemplate (ritirato) |
androidx.car.app.NAVIGATION_TEMPLATES |
Navigazione |
RoutePreviewNavigationTemplate (ritirato) |
androidx.car.app.NAVIGATION_TEMPLATES |
Navigazione |
Dichiarare l'autorizzazione per la superficie
Oltre all'autorizzazione richiesta per il modello utilizzato dall'app,
l'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 superficie
Per accedere all'Surface
fornito dall'host, devi implementare un
SurfaceCallback
e fornire
l'implementazione al servizio
di auto AppManager
. L'attuale Surface
viene trasmesso 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);
Comprendere l'area visibile della superficie
L'organizzatore può disegnare gli elementi dell'interfaccia utente per i modelli sopra
la mappa. L'host comunica l'area della superficie che è garantita essere
sgombra e completamente visibile all'utente chiamando il metodo
SurfaceCallback.onVisibleAreaChanged
. Inoltre, 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 attuale.
Ad esempio, quando un'app di navigazione utilizza
NavigationTemplate
con una barra delle azioni in alto, la barra delle azioni può nascondersi
quando l'utente non interagisce con lo schermo per un po' di tempo per lasciare più
spazio alla mappa. In questo caso, esiste un callback a onStableAreaChanged
e
onVisibleAreaChanged
con lo stesso rettangolo. Quando la striscia delle azioni è nascosta,
viene chiamato solo onVisibleAreaChanged
con l'area più grande. Se l'utente
interagisce con lo schermo, viene chiamato di nuovo solo onVisibleAreaChanged
con
il primo rettangolo.
Supportare il tema scuro
Le app devono ridisegnare la mappa sull'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 decidere se disegnare una mappa scura, puoi utilizzare il metodo
CarContext.isDarkMode
. Ogni volta che lo stato del tema scuro cambia, ricevi una chiamata a
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 ulteriori indicazioni, consulta Disegno del display del cluster.
Consentire agli utenti di interagire con la mappa
Quando utilizzi i seguenti modelli, puoi aggiungere il supporto per l'interazione degli utenti con le mappe che disegni, ad esempio consentendo loro di vedere diverse parti di una mappa con lo zoom e la panoramica.
Modello | Interattività supportata dal livello API Car App |
---|---|
NavigationTemplate |
2 |
PlaceListNavigationTemplate (ritirato) |
4 |
RoutePreviewNavigationTemplate (ritirato) |
4 |
MapTemplate (ritirato) |
5 (introduzione del modello) |
MapWithContentTemplate |
7 (introduzione del modello) |
Implementare i callback di interattività
L'interfaccia SurfaceCallback
dispone di diversi metodi di callback che puoi implementare per aggiungere interattività alle mappe create
con i modelli nella sezione precedente:
Interazione | SurfaceCallback metodo |
Supportato a partire dal livello API Car App |
---|---|---|
Tocca | onClick |
5 |
Pizzica per eseguire lo zoom | onScale |
2 |
Trascinamento con un solo tocco | onScroll |
2 |
Trasferimento con un solo tocco | onFling |
2 |
Tocca due volte | onScale (con fattore di scala determinato dall'host del modello) |
2 |
Rotazione in modalità panoramica | onScroll (con fattore di distanza determinato dall'host del modello) |
2 |
Aggiungere una striscia di azioni della mappa
Questi modelli possono avere una barra delle azioni della mappa per azioni correlate alla mappa, come ingrandire e ridurre, ricentrare, visualizzare una bussola e altre azioni che scegli di visualizzare. La barra delle azioni della mappa può contenere fino a quattro pulsanti solo con icone che possono essere aggiornati senza influire sulla profondità dell'attività. Viene nascosto durante lo stato di inattività e riappare nello stato attivo.
Per ricevere callback di interattività della mappa, devi aggiungere un pulsante Action.PAN
nella barra delle azioni della mappa. Quando l'utente
preme il pulsante di panoramica, l'organizzatore entra in modalità panoramica, come descritto nella sezione
successiva.
Se la tua app omette il pulsante Action.PAN
nella barra delle azioni della mappa, non riceve l'input dell'utente dai metodi
SurfaceCallback
e l'host esce da qualsiasi modalità
panoramica attivata in precedenza.
Su un touchscreen, il pulsante Panoramica non viene visualizzato.
Informazioni sulla modalità panoramica
In modalità panoramica, l'host del modello traduce l'input dell'utente da dispositivi di input non touch, come controller rotativi e touchpad, nei metodi di
SurfaceCallback
appropriati. Rispondi all'azione dell'utente per attivare o disattivare la modalità panoramica
con il metodo
setPanModeListener
in NavigationTemplate.Builder
. L'organizzatore può nascondere altri componenti dell'interfaccia utente nel modello mentre l'utente è in modalità panoramica.
Interagire con l'utente
La tua app può interagire con l'utente utilizzando pattern simili a quelli di un'app mobile.
Gestire l'input utente
La tua app può rispondere all'input utente passando i listener appropriati ai modelli che li supportano. Il seguente snippet mostra come creare un
modello Action
che imposta un
OnClickListener
che
richiama un metodo definito dal codice della tua app:
Kotlin
val action = Action.Builder() .setTitle("Navigate") .setOnClickListener(::onClickNavigate) .build()
Java
Action action = new Action.Builder() .setTitle("Navigate") .setOnClickListener(this::onClickNavigate) .build();
Il metodo onClickNavigate
può quindi avviare l'app di navigazione predefinita per l'auto utilizzando il metodo CarContext.startCarApp
:
Kotlin
private fun onClickNavigate() { val intent = Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:0,0?q=" + address)) carContext.startCarApp(intent) }
Java
private void onClickNavigate() { Intent intent = new Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:0,0?q=" + address)); getCarContext().startCarApp(intent); }
Per maggiori dettagli su come avviare le app, incluso il formato dell'intent
ACTION_NAVIGATE
, consulta la sezione Avviare un'app per auto con un intent.
Alcune azioni, come quelle che richiedono di indirizzare l'utente a continuare l'interazione sui propri dispositivi mobili, sono consentite solo quando l'auto è parcheggiata.
Puoi utilizzare
ParkedOnlyOnClickListener
per implementare queste azioni. Se l'auto non è parcheggiata, l'host mostra
all'utente un'indicazione che l'azione non è consentita in questo caso. Se l'auto
è parcheggiata, il codice viene eseguito normalmente. Il seguente snippet mostra come
utilizzare ParkedOnlyOnClickListener
per aprire una schermata delle impostazioni sul dispositivo mobile:
Kotlin
val row = Row.Builder() .setTitle("Open Settings") .setOnClickListener(ParkedOnlyOnClickListener.create(::openSettingsOnPhone)) .build()
Java
Row row = new Row.Builder() .setTitle("Open Settings") .setOnClickListener(ParkedOnlyOnClickListener.create(this::openSettingsOnPhone)) .build();
Mostra notifiche
Le notifiche inviate al dispositivo mobile vengono visualizzate sullo schermo dell'auto solo se
sono estese con un
CarAppExtender
.
Alcuni attributi delle notifiche, come titolo, testo, icona e azioni dei contenuti,
possono essere impostati in CarAppExtender
, ignorando gli attributi della notifica
quando vengono visualizzati sullo schermo dell'auto.
Il seguente snippet mostra come inviare una notifica allo schermo dell'auto che mostra un titolo diverso da quello visualizzato sul dispositivo mobile:
Kotlin
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) .setContentTitle(titleOnThePhone) .extend( CarAppExtender.Builder() .setContentTitle(titleOnTheCar) ... .build()) .build()
Java
Notification notification = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) .setContentTitle(titleOnThePhone) .extend( new CarAppExtender.Builder() .setContentTitle(titleOnTheCar) ... .build()) .build();
Le notifiche possono influire sulle seguenti parti dell'interfaccia utente:
- All'utente potrebbe essere mostrata una notifica di avviso.
- Nel centro notifiche potrebbe essere aggiunto un elemento, facoltativamente con un badge visibile nella barra.
- Per le app di navigazione, la notifica potrebbe essere visualizzata nel widget della barra come descritto in Notifiche passo passo.
Puoi scegliere come configurare le notifiche della tua app in modo che influiscano su ciascuno di questi elementi dell'interfaccia utente utilizzando la priorità della notifica, come descritto nella documentazione CarAppExtender
.
Se
NotificationCompat.Builder.setOnlyAlertOnce
viene chiamato con un valore di true
, una notifica di priorità elevata viene visualizzata come
HUN una sola volta.
Per saperne di più su come progettare le notifiche dell'app per auto, consulta la guida di Google Design for Driving relativa alle Notifiche.
Mostra avvisi popup
La tua app può visualizzare un messaggio di notifica utilizzando
CarToast
come mostrato in questo snippet:
Kotlin
CarToast.makeText(carContext, "Hello!", CarToast.LENGTH_SHORT).show()
Java
CarToast.makeText(getCarContext(), "Hello!", CarToast.LENGTH_SHORT).show();
Richiedi autorizzazioni
Se la tua app ha bisogno di accedere a dati o azioni con limitazioni, ad esempio
la posizione, si applicano le regole standard delle autorizzazioni
Android. Per richiedere un'autorizzazione, puoi utilizzare il metodo
CarContext.requestPermissions()
.
Il vantaggio di utilizzare
CarContext.requestPermissions()
, anziché
API Android standard, è
che non devi avviare il tuo Activity
per
creare la finestra di dialogo delle autorizzazioni. Inoltre, puoi utilizzare lo stesso codice sia su
Android Auto che su Android Automotive OS, anziché dover creare
flussi dipendenti dalla piattaforma.
Stilizzare la finestra di dialogo delle autorizzazioni su Android Auto
Su Android Auto, la finestra di dialogo delle autorizzazioni per l'utente viene visualizzata sullo smartphone.
Per impostazione predefinita, non ci sarà uno sfondo dietro la finestra di dialogo. Per impostare uno sfondo
personalizzato, dichiara un tema dell'app per auto nel tuo
file AndroidManifest.xml
e imposta l'attributo carPermissionActivityLayout
per il tema dell'app per auto.
<meta-data android:name="androidx.car.app.theme" android:resource="@style/MyCarAppTheme />
Dopodiché, imposta l'attributo carPermissionActivityLayout
per il tema dell'app per auto:
<resources> <style name="MyCarAppTheme"> <item name="carPermissionActivityLayout">@layout/my_custom_background</item> </style> </resources>
Avviare un'app per auto con un intent
Puoi chiamare il metodo
CarContext.startCarApp
per eseguire una delle seguenti azioni:
- Apri il tastierino per effettuare una chiamata.
- Avvia la navigazione passo passo verso una posizione con l'app di navigazione per auto predefinita.
- Avvia la tua app con un intent.
L'esempio seguente mostra come creare una notifica con un'azione che
apre la tua app con una schermata che mostra i dettagli di una prenotazione di parcheggio.
Estendi l'istanza di notifica con un intent di contenuti che contiene un
PendingIntent
che racchiude un intent esplicito
nell'azione della tua app:
Kotlin
val notification = notificationBuilder ... .extend( CarAppExtender.Builder() .setContentIntent( PendingIntent.getBroadcast( context, ACTION_VIEW_PARKING_RESERVATION.hashCode(), Intent(ACTION_VIEW_PARKING_RESERVATION) .setComponent(ComponentName(context, MyNotificationReceiver::class.java)), 0)) .build())
Java
Notification notification = notificationBuilder ... .extend( new CarAppExtender.Builder() .setContentIntent( PendingIntent.getBroadcast( context, ACTION_VIEW_PARKING_RESERVATION.hashCode(), new Intent(ACTION_VIEW_PARKING_RESERVATION) .setComponent(new ComponentName(context, MyNotificationReceiver.class)), 0)) .build());
La tua app deve anche dichiarare un
BroadcastReceiver
che viene
richiamato per elaborare l'intent quando l'utente seleziona l'azione nell'interfaccia
di notifica e richiama
CarContext.startCarApp
con un intent che include l'URI dati:
Kotlin
class MyNotificationReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val intentAction = intent.action if (ACTION_VIEW_PARKING_RESERVATION == intentAction) { CarContext.startCarApp( intent, Intent(Intent.ACTION_VIEW) .setComponent(ComponentName(context, MyCarAppService::class.java)) .setData(Uri.fromParts(MY_URI_SCHEME, MY_URI_HOST, intentAction))) } } }
Java
public class MyNotificationReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String intentAction = intent.getAction(); if (ACTION_VIEW_PARKING_RESERVATION.equals(intentAction)) { CarContext.startCarApp( intent, new Intent(Intent.ACTION_VIEW) .setComponent(new ComponentName(context, MyCarAppService.class)) .setData(Uri.fromParts(MY_URI_SCHEME, MY_URI_HOST, intentAction))); } } }
Infine, il metodo
Session.onNewIntent
nella tua app gestisce questo intent inserendo la schermata di prenotazione del parcheggio
nello stack, se non è già in primo piano:
Kotlin
override fun onNewIntent(intent: Intent) { val screenManager = carContext.getCarService(ScreenManager::class.java) val uri = intent.data if (uri != null && MY_URI_SCHEME == uri.scheme && MY_URI_HOST == uri.schemeSpecificPart && ACTION_VIEW_PARKING_RESERVATION == uri.fragment ) { val top = screenManager.top if (top !is ParkingReservationScreen) { screenManager.push(ParkingReservationScreen(carContext)) } } }
Java
@Override public void onNewIntent(@NonNull Intent intent) { ScreenManager screenManager = getCarContext().getCarService(ScreenManager.class); Uri uri = intent.getData(); if (uri != null && MY_URI_SCHEME.equals(uri.getScheme()) && MY_URI_HOST.equals(uri.getSchemeSpecificPart()) && ACTION_VIEW_PARKING_RESERVATION.equals(uri.getFragment()) ) { Screen top = screenManager.getTop(); if (!(top instanceof ParkingReservationScreen)) { screenManager.push(new ParkingReservationScreen(getCarContext())); } } }
Per ulteriori informazioni su come gestire le notifiche per l'app per l'auto, consulta la sezione Visualizzare le notifiche.
Limitazioni dei modelli
L'host limita il numero di modelli da visualizzare per una determinata attività a un massimo di cinque, di cui l'ultimo modello deve essere di uno dei seguenti tipi:
NavigationTemplate
PaneTemplate
MessageTemplate
MediaPlaybackTemplate
SignInTemplate
LongMessageTemplate
Tieni presente che questo limite si applica al numero di modelli e non al numero di istanze Screen
nello stack. Ad esempio, se un'app invia due modelli mentre si trova nella schermata A e poi esegue il push della schermata B, ora può inviare altri tre modelli. In alternativa, se ogni schermata è strutturata
per inviare un singolo modello, l'app può inserire cinque istanze di schermata nello
stack ScreenManager
.
Esistono casi speciali per queste limitazioni: aggiornamenti dei modelli e operazioni di backup e reimpostazione.
Aggiornamenti dei modelli
Alcuni aggiornamenti dei contenuti non vengono conteggiati ai fini del limite dei modelli. In generale,
se un'app esegue il push di un nuovo modello dello stesso tipo e contenente
gli stessi contenuti principali del modello precedente, il nuovo modello non viene
conteggiato ai fini della quota. Ad esempio, l'aggiornamento dello stato di attivazione/disattivazione di una riga in un
ListTemplate
non viene conteggiato
ai fini della quota. Consulta la documentazione dei singoli modelli per scoprire di più
sui tipi di aggiornamenti dei contenuti che possono essere considerati un aggiornamento.
Operazioni di back
Per attivare i sottoflussi all'interno di un'attività, l'host rileva quando un'app mostra un
Screen
dallo stack ScreenManager
e aggiorna
la quota rimanente in base al numero di modelli di cui l'app sta
tornando indietro.
Ad esempio, se l'app invia due modelli nella schermata A, poi visualizza la schermata B e invia altri due modelli, all'app rimane una quota. Se l'app torna alla schermata A, l'host reimposta la quota su tre, perché l'app è tornata indietro di due modelli.
Tieni presente che, quando torna a una schermata, un'app deve inviare un modello dello stesso tipo di quello inviato l'ultima volta da quella schermata. L'invio di qualsiasi altro tipo di modello causa un errore. Tuttavia, se il tipo rimane lo stesso durante un'operazione di ritorno, un'app può modificare liberamente i contenuti del modello senza influire sulla quota.
Operazioni di ripristino
Alcuni modelli hanno una semantica speciale che indica la fine di un'attività. Ad esempio, la
NavigationTemplate
è una visualizzazione che dovrebbe rimanere sullo schermo e aggiornarsi con nuove
indicazioni stradali per l'utente. Quando raggiunge uno di questi
modelli, l'host reimposta la quota del modello, trattandolo come se
fosse il primo passaggio di una nuova attività. In questo modo, l'app può iniziare una nuova attività.
Consulta la documentazione dei singoli modelli per vedere quali attivano un ripristino
sull'host.
Se l'organizzatore riceve un intent per avviare l'app da un'azione di notifica o dal launcher, la quota viene reimpostata. Questo meccanismo consente a un'app di iniziare un nuovo flusso di attività dalle notifiche ed è valido anche se un'app è già associata e in primo piano.
Per ulteriori dettagli su come visualizzare le notifiche dell'app sullo schermo dell'auto, consulta la sezione Visualizzare le notifiche. Consulta la sezione Avviare un'app per auto con un intent per informazioni su come avviare l'app da un'azione di notifica.
API Connection
Puoi determinare se la tua app è in esecuzione su Android Auto o Android
Automotive OS utilizzando l'API
CarConnection
per recuperare le informazioni di connessione in fase di runtime.
Ad esempio, in Session
dell'app per l'auto, inizializza un CarConnection
e
iscriviti agli aggiornamenti di LiveData
:
Kotlin
CarConnection(carContext).type.observe(this, ::onConnectionStateUpdated)
Java
new CarConnection(getCarContext()).getType().observe(this, this::onConnectionStateUpdated);
Nell'observer, puoi reagire alle modifiche dello stato della connessione:
Kotlin
fun onConnectionStateUpdated(connectionState: Int) { val message = when(connectionState) { CarConnection.CONNECTION_TYPE_NOT_CONNECTED -> "Not connected to a head unit" CarConnection.CONNECTION_TYPE_NATIVE -> "Connected to Android Automotive OS" CarConnection.CONNECTION_TYPE_PROJECTION -> "Connected to Android Auto" else -> "Unknown car connection type" } CarToast.makeText(carContext, message, CarToast.LENGTH_SHORT).show() }
Java
private void onConnectionStateUpdated(int connectionState) { String message; switch(connectionState) { case CarConnection.CONNECTION_TYPE_NOT_CONNECTED: message = "Not connected to a head unit"; break; case CarConnection.CONNECTION_TYPE_NATIVE: message = "Connected to Android Automotive OS"; break; case CarConnection.CONNECTION_TYPE_PROJECTION: message = "Connected to Android Auto"; break; default: message = "Unknown car connection type"; break; } CarToast.makeText(getCarContext(), message, CarToast.LENGTH_SHORT).show(); }
API Constraints
Auto diverse possono consentire la visualizzazione di un numero diverso di istanze di Item
all'utente contemporaneamente. Utilizza
ConstraintManager
per controllare il limite di contenuti in fase di runtime e impostare il numero appropriato di elementi
nei tuoi modelli.
Inizia richiedendo un ConstraintManager
al CarContext
:
Kotlin
val manager = carContext.getCarService(ConstraintManager::class.java)
Java
ConstraintManager manager = getCarContext().getCarService(ConstraintManager.class);
Puoi quindi eseguire query sull'oggetto ConstraintManager
recuperato per il limite di contenuti pertinente. Ad esempio, per ottenere il numero di elementi che possono essere visualizzati in
una griglia, chiama
getContentLimit
con
CONTENT_LIMIT_TYPE_GRID
:
Kotlin
val gridItemLimit = manager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_GRID)
Java
int gridItemLimit = manager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_GRID);
Aggiungere un flusso di accesso
Se la tua app offre un'esperienza di accesso per gli utenti, puoi utilizzare modelli come
SignInTemplate
e LongMessageTemplate
con il livello API Car App 2 e versioni successive per gestire l'accesso alla tua app sull'unità principale dell'auto.
Per creare un SignInTemplate
, definisci un SignInMethod
. Al momento, la raccolta di app per auto supporta i seguenti metodi di accesso:
InputSignInMethod
per l'accesso con nome utente/password.PinSignInMethod
per l'accesso con PIN, in cui l'utente collega il proprio account dallo smartphone utilizzando un PIN visualizzato sulla head unit.ProviderSignInMethod
per l'accesso del provider, ad esempio Accedi con Google e One Tap.QRCodeSignInMethod
per l'accesso con codice QR, in cui l'utente scansiona un codice QR per completare l'accesso sul proprio smartphone. Questa funzionalità è disponibile con l'API Car di livello 4 e versioni successive.
Ad esempio, per implementare un modello che raccolga la password dell'utente, inizia creando un InputCallback
per elaborare e convalidare l'input dell'utente:
Kotlin
val callback = object : InputCallback { override fun onInputSubmitted(text: String) { // You will receive this callback when the user presses Enter on the keyboard. } override fun onInputTextChanged(text: String) { // You will receive this callback as the user is typing. The update // frequency is determined by the host. } }
Java
InputCallback callback = new InputCallback() { @Override public void onInputSubmitted(@NonNull String text) { // You will receive this callback when the user presses Enter on the keyboard. } @Override public void onInputTextChanged(@NonNull String text) { // You will receive this callback as the user is typing. The update // frequency is determined by the host. } };
È necessario un InputCallback
per InputSignInMethod
Builder
.
Kotlin
val passwordInput = InputSignInMethod.Builder(callback) .setHint("Password") .setInputType(InputSignInMethod.INPUT_TYPE_PASSWORD) ... .build()
Java
InputSignInMethod passwordInput = new InputSignInMethod.Builder(callback) .setHint("Password") .setInputType(InputSignInMethod.INPUT_TYPE_PASSWORD) ... .build();
Infine, utilizza il nuovo InputSignInMethod
per creare un SignInTemplate
.
Kotlin
SignInTemplate.Builder(passwordInput) .setTitle("Sign in with username and password") .setInstructions("Enter your password") .setHeaderAction(Action.BACK) ... .build()
Java
new SignInTemplate.Builder(passwordInput) .setTitle("Sign in with username and password") .setInstructions("Enter your password") .setHeaderAction(Action.BACK) ... .build();
Utilizza AccountManager
Le app per Android Automotive OS che prevedono l'autenticazione devono utilizzare AccountManager per i seguenti motivi:
- Migliore esperienza utente e facilità di gestione dell'account: gli utenti possono gestire facilmente tutti i loro account dal menu degli account nelle impostazioni di sistema, inclusi l'accesso e la disconnessione.
- Esperienze"Ospite": poiché le auto sono dispositivi condivisi, gli OEM possono attivare esperienze per gli ospiti nel veicolo, in cui non è possibile aggiungere account.
Aggiungere varianti di stringhe di testo
Le diverse dimensioni dello schermo dell'auto possono mostrare quantità diverse di testo. Con l'API Car App
di livello 2 e superiore, puoi specificare più varianti di una stringa di testo per adattarla al meglio
allo schermo. Per vedere dove sono accettate le varianti di testo, cerca i modelli e i componenti che accettano un CarText
.
Puoi aggiungere varianti di stringhe di testo a un CarText
con il metodo
CarText.Builder.addVariant()
:
Kotlin
val itemTitle = CarText.Builder("This is a very long string") .addVariant("Shorter string") ... .build()
Java
CarText itemTitle = new CarText.Builder("This is a very long string") .addVariant("Shorter string") ... .build();
Puoi quindi utilizzare questo CarText
, ad esempio come testo principale di un
GridItem
.
Kotlin
GridItem.Builder() .addTitle(itemTitle) ... .build()
Java
new GridItem.Builder() .addTitle(itemTitle) ... build();
Aggiungi le stringhe in ordine decrescente di preferenza, ad esempio dalla più lunga alla più corta. L'host sceglie la stringa della lunghezza appropriata in base allo spazio disponibile sullo schermo dell'auto.
Aggiungere CarIcon in linea per le righe
Puoi aggiungere icone in linea con il testo per arricchire l'aspetto visivo della tua app utilizzando
CarIconSpan
.
Per ulteriori informazioni sulla creazione di questi intervalli, consulta la documentazione relativa a
CarIconSpan.create
. Consulta
Spantastic
text styling with Spans per una panoramica del funzionamento dello stile del testo con gli span.
Kotlin
val rating = SpannableString("Rating: 4.5 stars") rating.setSpan( CarIconSpan.create( // Create a CarIcon with an image of four and a half stars CarIcon.Builder(...).build(), // Align the CarIcon to the baseline of the text CarIconSpan.ALIGN_BASELINE ), // The start index of the span (index of the character '4') 8, // The end index of the span (index of the last 's' in "stars") 16, Spanned.SPAN_INCLUSIVE_INCLUSIVE ) val row = Row.Builder() ... .addText(rating) .build()
Java
SpannableString rating = new SpannableString("Rating: 4.5 stars"); rating.setSpan( CarIconSpan.create( // Create a CarIcon with an image of four and a half stars new CarIcon.Builder(...).build(), // Align the CarIcon to the baseline of the text CarIconSpan.ALIGN_BASELINE ), // The start index of the span (index of the character '4') 8, // The end index of the span (index of the last 's' in "stars") 16, Spanned.SPAN_INCLUSIVE_INCLUSIVE ); Row row = new Row.Builder() ... .addText(rating) .build();
API hardware per auto
A partire dal livello API 3 di Car App API, la libreria Car App Library include API che puoi utilizzare per accedere alle proprietà e ai sensori del veicolo.
Requisiti
Per utilizzare le API con Android Auto, inizia aggiungendo una dipendenza da
androidx.car.app:app-projected
al file build.gradle
per il modulo Android
Auto. Per Android Automotive OS, aggiungi una dipendenza da
androidx.car.app:app-automotive
al file build.gradle
per il modulo Android
Automotive OS.
Inoltre, nel file AndroidManifest.xml
devi
dichiarare le autorizzazioni pertinenti necessarie per
richiedere i dati dell'auto che vuoi utilizzare. Tieni presente che queste autorizzazioni devono essere
concesse anche a te dall'utente. Puoi utilizzare lo
stesso codice sia su Android Auto che su Android Automotive OS, invece
di dover creare flussi dipendenti dalla piattaforma. Tuttavia, le autorizzazioni necessarie
sono diverse.
CarInfo
Questa tabella descrive le proprietà mostrate dalle API
CarInfo
e le
autorizzazioni che devi richiedere per utilizzarle:
Metodi | Proprietà | Autorizzazioni Android Auto | Autorizzazioni di Android Automotive OS | Supportato a partire dal livello API Car App |
---|---|---|---|---|
fetchModel |
Marca, modello, anno | android.car.permission.CAR_INFO |
3 | |
fetchEnergyProfile |
Tipi di connettori EV, tipi di carburante | com.google.android.gms.permission.CAR_FUEL |
android.car.permission.CAR_INFO |
3 |
fetchExteriorDimensions
Questi dati sono disponibili solo su alcuni veicoli con Android Automotive OS con API 30 o versioni successive |
Dimensioni esterne | N/D | android.car.permission.CAR_INFO |
7 |
addTollListener
removeTollListener |
Stato tessera pedaggi, tipo di tessera pedaggi | 3 | ||
addEnergyLevelListener
removeEnergyLevelListener |
Livello batteria, livello carburante, livello carburante basso, autonomia rimanente | com.google.android.gms.permission.CAR_FUEL |
android.car.permission.CAR_ENERGY ,android.car.permission.CAR_ENERGY_PORTS ,android.car.permission.READ_CAR_DISPLAY_UNITS
|
3 |
addSpeedListener
removeSpeedListener |
Velocità effettiva, velocità visualizzata (mostrata sul display del cruscotto dell'auto) | com.google.android.gms.permission.CAR_SPEED |
android.car.permission.CAR_SPEED ,android.car.permission.READ_CAR_DISPLAY_UNITS |
3 |
addMileageListener
removeMileageListener
Avviso: il metodo |
Distanza odometro | com.google.android.gms.permission.CAR_MILEAGE |
Questi dati non sono disponibili su Android Automotive OS per le app installate dal Play Store. | 3 |
Ad esempio, per ottenere l'intervallo rimanente, crea un'istanza di un oggetto CarInfo
, quindi crea e registra un OnCarDataAvailableListener
:
Kotlin
val carInfo = carContext.getCarService(CarHardwareManager::class.java).carInfo val listener = OnCarDataAvailableListener<EnergyLevel> { data -> if (data.rangeRemainingMeters.status == CarValue.STATUS_SUCCESS) { val rangeRemaining = data.rangeRemainingMeters.value } else { // Handle error } } carInfo.addEnergyLevelListener(carContext.mainExecutor, listener) … // Unregister the listener when you no longer need updates carInfo.removeEnergyLevelListener(listener)
Java
CarInfo carInfo = getCarContext().getCarService(CarHardwareManager.class).getCarInfo(); OnCarDataAvailableListener<EnergyLevel> listener = (data) -> { if(data.getRangeRemainingMeters().getStatus() == CarValue.STATUS_SUCCESS) { float rangeRemaining = data.getRangeRemainingMeters().getValue(); } else { // Handle error } }; carInfo.addEnergyLevelListener(getCarContext().getMainExecutor(), listener); … // Unregister the listener when you no longer need updates carInfo.removeEnergyLevelListener(listener);
Non dare per scontato che i dati dell'auto siano sempre disponibili.
Se ricevi un errore, controlla lo
stato del
valore che hai richiesto per capire meglio perché i dati che hai richiesto non possono
essere recuperati. Consulta la
documentazione di riferimento per
la definizione completa della classe CarInfo
.
CarSensors
La classe CarSensors
ti consente di accedere ai dati di accelerometro, giroscopio, bussola e
posizione del veicolo. La disponibilità di questi valori può dipendere dall'OEM. Il formato dei dati dell'accelerometro, del giroscopio e della bussola è lo stesso che otterresti dall'API SensorManager
. Ad esempio,
per controllare la direzione del veicolo:
Kotlin
val carSensors = carContext.getCarService(CarHardwareManager::class.java).carSensors val listener = OnCarDataAvailableListener<Compass> { data -> if (data.orientations.status == CarValue.STATUS_SUCCESS) { val orientation = data.orientations.value } else { // Data not available, handle error } } carSensors.addCompassListener(CarSensors.UPDATE_RATE_NORMAL, carContext.mainExecutor, listener) … // Unregister the listener when you no longer need updates carSensors.removeCompassListener(listener)
Java
CarSensors carSensors = getCarContext().getCarService(CarHardwareManager.class).getCarSensors(); OnCarDataAvailableListener<Compass> listener = (data) -> { if (data.getOrientations().getStatus() == CarValue.STATUS_SUCCESS) { List<Float> orientations = data.getOrientations().getValue(); } else { // Data not available, handle error } }; carSensors.addCompassListener(CarSensors.UPDATE_RATE_NORMAL, getCarContext().getMainExecutor(), listener); … // Unregister the listener when you no longer need updates carSensors.removeCompassListener(listener);
Per accedere ai dati sulla posizione dell'auto, devi anche dichiarare e richiedere l'autorizzazione
android.permission.ACCESS_FINE_LOCATION
.
Test
Per simulare i dati dei sensori durante i test su Android Auto, consulta le sezioni Sensori e Configurazione sensore della guida all'unità principale di prova. Per simulare i dati dei sensori durante i test su Android Automotive OS, consulta la sezione Emulazione dello stato dell'hardware della guida all'emulatore Android Automotive OS.
Cicli di vita di CarAppService, Session e Screen
Le classi Session
e
Screen
implementano l'interfaccia
LifecycleOwner
. Man mano che l'utente interagisce con l'app, vengono richiamati i callback del ciclo di vita degli oggetti Session
e Screen
, come descritto nei diagrammi seguenti.
Cicli di vita di un CarAppService e di una sessione

Session
ciclo di vitaPer tutti i dettagli, consulta la documentazione del metodo
Session.getLifecycle
.
Il ciclo di vita di una schermata

Screen
ciclo di vitaPer tutti i dettagli, consulta la documentazione del metodo
Screen.getLifecycle
.
Registrare dal microfono dell'auto
Utilizzando l'CarAppService
della tua app e l'API CarAudioRecord
, puoi concedere alla tua app l'accesso al microfono dell'auto dell'utente. Gli utenti devono concedere
alla tua app l'autorizzazione per accedere al microfono dell'auto. La tua app può registrare ed elaborare l'input dell'utente all'interno dell'app.
Autorizzazione per la registrazione
Prima di registrare qualsiasi audio, devi prima dichiarare l'autorizzazione alla registrazione nel tuo
AndroidManifest.xml
e richiedere all'utente di concederla.
<manifest ...>
...
<uses-permission android:name="android.permission.RECORD_AUDIO" />
...
</manifest>
Devi richiedere l'autorizzazione per registrare in fase di runtime. Per informazioni dettagliate su come richiedere un'autorizzazione nell'app per l'auto, consulta la sezione Richiedi autorizzazioni.
Registra l'audio
Dopo che l'utente ha dato l'autorizzazione alla registrazione, puoi registrare l'audio ed elaborare la registrazione.
Kotlin
val carAudioRecord = CarAudioRecord.create(carContext) carAudioRecord.startRecording() val data = ByteArray(CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE) while(carAudioRecord.read(data, 0, CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE) >= 0) { // Use data array // Potentially call carAudioRecord.stopRecording() if your processing finds end of speech } carAudioRecord.stopRecording()
Java
CarAudioRecord carAudioRecord = CarAudioRecord.create(getCarContext()); carAudioRecord.startRecording(); byte[] data = new byte[CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE]; while (carAudioRecord.read(data, 0, CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE) >= 0) { // Use data array // Potentially call carAudioRecord.stopRecording() if your processing finds end of speech } carAudioRecord.stopRecording();
Focus audio
Quando registri dal microfono dell'auto, acquisisci prima la messa a fuoco dell'audio per assicurarti che i contenuti multimediali in riproduzione vengano interrotti. Se perdi la messa a fuoco dell'audio, interrompi la registrazione.
Ecco un esempio di come acquisire lo stato attivo audio:
Kotlin
val carAudioRecord = CarAudioRecord.create(carContext) // Take audio focus so that user's media is not recorded val audioAttributes = AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) // Use the most appropriate usage type for your use case .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE) .build() val audioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) .setAudioAttributes(audioAttributes) .setOnAudioFocusChangeListener { state: Int -> if (state == AudioManager.AUDIOFOCUS_LOSS) { // Stop recording if audio focus is lost carAudioRecord.stopRecording() } } .build() if (carContext.getSystemService(AudioManager::class.java) .requestAudioFocus(audioFocusRequest) != AudioManager.AUDIOFOCUS_REQUEST_GRANTED ) { // Don't record if the focus isn't granted return } carAudioRecord.startRecording() // Process the audio and abandon the AudioFocusRequest when done
Java
CarAudioRecord carAudioRecord = CarAudioRecord.create(getCarContext()); // Take audio focus so that user's media is not recorded AudioAttributes audioAttributes = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) // Use the most appropriate usage type for your use case .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE) .build(); AudioFocusRequest audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) .setAudioAttributes(audioAttributes) .setOnAudioFocusChangeListener(state -> { if (state == AudioManager.AUDIOFOCUS_LOSS) { // Stop recording if audio focus is lost carAudioRecord.stopRecording(); } }) .build(); if (getCarContext().getSystemService(AudioManager.class).requestAudioFocus(audioFocusRequest) != AUDIOFOCUS_REQUEST_GRANTED) { // Don't record if the focus isn't granted return; } carAudioRecord.startRecording(); // Process the audio and abandon the AudioFocusRequest when done
Libreria di test
La libreria
di test Android for Cars fornisce classi ausiliarie che puoi utilizzare per convalidare il comportamento della tua app in un ambiente di test.
Ad esempio, il
SessionController
ti consente di simulare una connessione all'host e verificare che vengano creati e restituiti i
Screen
e
Template
corretti.
Consulta gli Esempi per esempi di utilizzo.
Segnalare un problema relativo alla libreria di app Android for Cars
Se riscontri un problema con la libreria, segnalalo utilizzando Google Issue Tracker. Assicurati di compilare tutte le informazioni richieste nel modello di problema.
Prima di segnalare un nuovo problema, verifica se è elencato nelle note di rilascio della libreria o segnalato nell'elenco dei problemi. Puoi iscriverti e votare i problemi facendo clic sulla stella nel tracker. Per ulteriori informazioni, consulta la sezione Abbonarsi a un problema.