Utilizzare la libreria di app di Android for Cars

La raccolta di app Android for Cars ti consente di visualizzare la navigazione, il punto d'interesse (PDI) e la connessione Internet delle cose (IOT) le app all'auto. Offre una serie di modelli pensati per rispondere alle distrazioni del conducente standard e nella cura di dettagli come la varietà di fattori dello schermo dell'auto e le modalità di input.

Questa guida fornisce una panoramica delle funzionalità e dei concetti principali della libreria. ti guida nella procedura di configurazione di un'app di base.

Prima di iniziare

  1. Rivedi la progettazione per la guida pagine relative alla Raccolta di app per auto
  2. Esamina i termini e concetti chiave nel seguente articolo .
  3. Acquisisci familiarità con il sistema Android Auto UI e Android Automotive OS la progettazione.
  4. Consulta le Note di rilascio.
  5. Esamina gli esempi.

Termini e concetti chiave

Modelli e modelli
L'interfaccia utente è rappresentata da un grafico di oggetti modello che possono essere disposti in modo diverso, come consentito dal modello a cui appartengono a. I modelli sono un sottoinsieme dei modelli che possono fungere da radice grafici. I modelli includono le informazioni da mostrare all'utente nei di testo e immagini, nonché attributi per configurare gli aspetti l'aspetto visivo di tali informazioni, ad esempio colori del testo o immagini dimensioni. L'host converte i modelli in viste progettate per soddisfare gli standard della distrazione del conducente e si prende cura di dettagli come la varietà di fattori dello schermo dell'auto e modalità di immissione.
Moderatore
L'host è il componente di backend che implementa la funzionalità offerta dalle API della libreria in modo che l'app possa essere eseguita in auto. La le responsabilità dell'host variano, ad esempio scoprire l'app e gestire il suo ciclo di vita, fino alla conversione dei modelli in visualizzazioni e all'invio di notifiche all'app delle interazioni degli utenti. Sui dispositivi mobili, questo host è implementato da Android Automatico. Su Android Automotive OS, questo host è installato come app di sistema.
Limitazioni relative al modello
Diversi modelli applicano limitazioni nei contenuti dei rispettivi modelli. Per Ad esempio, i modelli di elenco hanno dei limiti al numero di elementi che possono essere presentati all'utente. I modelli hanno anche delle limitazioni essere connessi per formare il flusso di un'attività. Ad esempio, l'app può eseguire solo fino a cinque modelli. Consulta Limitazioni dei modelli per maggiori dettagli.
Screen
Screen è un corso fornito da libreria implementata dalle app per gestire l'interfaccia utente presentata ai utente. Un Screen ha un ciclo di vita e fornisce il meccanismo per consentire all'app di invia il modello da mostrare quando lo schermo è visibile. È possibile anche eseguire il push di Screen istanze ed è stato visualizzato automaticamente da e verso una lista di Screen, che garantisce il rispetto delle restrizioni del flusso del modello.
CarAppService
CarAppService è un classe Service astratta che la tua app devono implementare ed esportare per essere rilevati e gestiti dall'host. Il valore CarAppService della tua app è è responsabile della verifica dell'attendibilità di una connessione host createHostValidator e successivamente fornire Session per ogni connessione onCreateSession
Session

Session è una classe astratta l'app deve implementare e restituire utilizzando CarAppService.onCreateSession. Funge da punto di accesso per visualizzare le informazioni sullo schermo dell'auto. it ha un ciclo di vita che informa stato corrente dell'app sullo schermo dell'auto, ad esempio quando visibili o nascoste.

Quando viene avviata una Session, ad esempio Quando l'app viene avviata per la prima volta, l'host richiede il Screen da visualizzare utilizzando onCreateScreen: .

Installa la raccolta di app dell'auto

Visita la libreria Jetpack pagina di rilascio per istruzioni su come aggiungere la raccolta alla tua app.

Configurare i file manifest dell'app

Per poter creare un'app per auto, devi prima configurare il file manifest come segue.

Dichiara il tuo servizio CarAppService

L'host si connette alla tua app tramite Implementazione di CarAppService. Tu dichiarare questo servizio nel file manifest per consentire all'host di rilevare e connettersi alla tua app.

Devi anche dichiarare la categoria della tua app nel L'elemento <category> dell'app filtro per intent. Consulta l'elenco di 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 punto di l'app di interesse nel 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 una o più delle seguenti categorie nel filtro per intent quando dichiari CarAppService come descritto nella sezione precedente:

  • androidx.car.app.category.NAVIGATION: un'app che fornisce indicazioni passo passo le indicazioni stradali di navigazione. Consulta Creare app di navigazione per le auto per ulteriore documentazione su questa categoria.
  • androidx.car.app.category.POI: un'app che offre funzionalità pertinenti alla ricerca di punti d'interesse come parcheggi, stazioni di ricarica e distributori di benzina. Paga Creare app per punti d'interesse per le auto per documentazione aggiuntiva su questa categoria.
  • androidx.car.app.category.IOT: un'app che consente agli utenti di passare contenuti pertinenti azioni sui dispositivi connessi dall'auto. Paga Crea app Internet per le auto documentazione aggiuntiva su questa categoria.
di Gemini Advanced.

Consulta la pagina Qualità delle app per Android per le auto per descrizioni dettagliate di ogni categoria e criteri per l'appartenenza delle app.

Specifica il nome e l'icona dell'app

Devi specificare il nome e l'icona di un'app che l'host può utilizzare per rappresentare il tuo nell'interfaccia utente di sistema.

Puoi specificare il nome e l'icona dell'app utilizzati per rappresentare la tua app utilizzando label e Attributi 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 nel <service>, l'host torna ai valori specificati per <application>.

Impostare un tema personalizzato

Per impostare un tema personalizzato per la tua app per auto, aggiungi un <meta-data> nel tuo , come segue:

<meta-data
    android:name="androidx.car.app.theme"
    android:resource="@style/MyCarAppTheme />

Quindi, dichiara la tua risorsa per lo stile in Imposta i seguenti attributi per il tuo tema app auto personalizzato:

<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 le funzionalità della libreria sono supportate dall'host del modello su un veicolo. Per recuperare il livello API più alto dell'app Car App supportato da un host, utilizza il getCarAppApiLevel() .

Dichiara il livello API minimo dell'app Car App supportato dalla tua app nel tuo File AndroidManifest.xml:

<manifest ...>
    <application ...>
        <meta-data
            android:name="androidx.car.app.minCarApiLevel"
            android:value="1"/>
    </application>
</manifest>

Consulta la documentazione per RequiresCarApi per informazioni dettagliate su come mantenere la compatibilità con le versioni precedenti il livello API minimo richiesto per utilizzare una funzionalità. Per una definizione di quale API livello necessario per utilizzare una determinata funzione della libreria di app per auto, controlla documentazione di riferimento CarAppApiLevels

Crea il tuo CarAppService e la sessione

La tua app deve estendere CarAppService e implementano le sue onCreateSession che restituisce un valore 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 che restituisce l'istanza Screen per 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 dell'auto deve essere avviata da uno schermo che non dalla schermata Home o di destinazione dell'app, ad esempio per gestire i link diretti, puoi pre-separare uno stack di schermi usando ScreenManager.push prima di tornare da onCreateScreen. Il pre-seeding consente agli utenti di tornare alle schermate precedenti dalla prima schermata mostrata nell'app.

Crea la tua schermata iniziale

Puoi creare le schermate visualizzate dalla tua app definendo classi che estendono Screen corso e ne implementa la relativa implementazione onGetTemplate , che restituisce Template che rappresenta l'istanza lo stato dell'UI da visualizzare sullo schermo dell'auto.

Il seguente snippet mostra come dichiarare un Screen che utilizza un PaneTemplate modello per mostrare un semplice "Hello World!" stringa:

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

Il corso CarContext è un Sottoclasse ContextWrapper accessibile ai tuoi dati Session e Screen di istanze. Fornisce l'accesso ai servizi per auto, come ScreenManager per la gestione screen stack; il AppManager per informazioni generali relative all'app funzionalità, come l'accesso all'oggetto Surface per disegno di mappe; e NavigationManager utilizzata dalle app di navigazione passo passo per comunicare la navigazione metadati e altri correlati alla navigazione eventi con l'organizzatore.

Vedi Accedere alla navigazione. modelli per un elenco completo delle funzionalità della libreria disponibili per le app di navigazione.

CarContext offre anche altre per le funzionalità, come la possibilità di caricare risorse disegnabili utilizzando la configurazione dallo schermo dell'auto, avviando un'app nell'auto usando gli intent. e indicando se la tua app deve visualizzare la mappa con il tema scuro.

Implementazione della navigazione nelle schermate

Le app spesso presentano diverse schermate, ognuna delle quali può utilizzare i diversi modelli a cui l'utente può navigare mentre interagisce l'interfaccia visualizzata sullo schermo.

Il corso ScreenManager fornisce una serie di schermate che puoi utilizzare per eseguire il push delle schermate che possono essere visualizzate automaticamente Quando l'utente seleziona un pulsante Indietro nello schermo dell'auto o utilizza l'hardware. è disponibile in alcune auto.

Lo snippet seguente mostra come aggiungere un'azione Indietro a un modello di messaggio come nonché un'azione che visualizzi una nuova schermata quando 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 standard Action che automaticamente chiama ScreenManager.pop. Questo comportamento può essere ignorato utilizzando il comando OnBackPressedDispatcher disponibile dal CarContext.

Per garantire che l'app sia sicura da usare durante la guida, la pila di schermate può avere un valore massimo fino a cinque schermi. Consulta le limitazioni relative ai modelli per ulteriori dettagli.

Aggiornare i contenuti di un modello

La tua app può richiedere i contenuti di un Annullamento della validità di Screen mediante la chiamata del metodo Screen.invalidate. L'organizzatore richiama successivamente nella console Screen.onGetTemplate 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 conti il nuovo modello rispetto alla quota del modello. Per ulteriori dettagli, consulta la sezione Limitazioni dei modelli.

Ti consigliamo di strutturare i tuoi schermi in modo da avere un'esperienza mappatura tra Screen e il tipo di che restituisce tramite l'implementazione di onGetTemplate.

Disegna mappe

Le app di navigazione e di punti di interesse (PDI) che utilizzano i seguenti modelli possono: Disegna mappe accedendo a una Surface:

Modello Autorizzazione modello Indicazioni per la categoria
NavigationTemplate androidx.car.app.NAVIGATION_TEMPLATES Navigazione
MapWithContentTemplate androidx.car.app.NAVIGATION_TEMPLATES OPPURE
androidx.car.app.MAP_TEMPLATES
Navigazione, PDI
MapTemplate (deprecato) androidx.car.app.NAVIGATION_TEMPLATES Navigazione
PlaceListNavigationTemplate (deprecato) androidx.car.app.NAVIGATION_TEMPLATES Navigazione
RoutePreviewNavigationTemplate (deprecato) androidx.car.app.NAVIGATION_TEMPLATES Navigazione

Dichiara l'autorizzazione di accesso alla piattaforma

Oltre all'autorizzazione richiesta per il modello utilizzato dalla tua app, la tua app deve dichiarare l'autorizzazione androidx.car.app.ACCESS_SURFACE nel relativo AndroidManifest.xml file per accedere alla piattaforma:

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

Accedi alla piattaforma

Per accedere al Surface fornito dall'host, devi implementare un SurfaceCallback e fornire l'implementazione in AppManager dell'auto. L'attuale Surface viene trasmesso al tuo SurfaceCallback nel parametro SurfaceContainer della Callback di onSurfaceAvailable() e onSurfaceDestroyed().

Kotlin

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

Java

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

Comprendi l'area visibile della superficie

L'organizzatore può aggiungere elementi dell'interfaccia utente ai modelli la mappa. L'host comunica l'area della superficie di cui viene garantito il non ostruita e completamente visibile all'utente chiamando il SurfaceCallback.onVisibleAreaChanged . Inoltre, per ridurre al minimo il numero di modifiche, l'organizzatore chiama la SurfaceCallback.onStableAreaChanged con il rettangolo più piccolo, che è sempre visibile in base modello corrente.

Ad esempio, quando un'app di navigazione utilizza NavigationTemplate con una striscia delle azioni nella parte superiore, la striscia delle azioni può nascondersi quando l'utente non interagisce con lo schermo da un po' per ottenere altre spazio per la mappa. In questo caso, viene richiamato il numero onStableAreaChanged e onVisibleAreaChanged con lo stesso rettangolo. Quando la barra delle azioni è nascosta, solo onVisibleAreaChanged viene chiamato con l'area più ampia. Se l'utente interagisce con lo schermo, quindi viene chiamato solo onVisibleAreaChanged con il primo rettangolo.

Supporto del tema scuro

Le app devono ridisegnare la propria mappa sull'istanza Surface con il tema scuro colori quando l'host determina le condizioni lo giustificano, come descritto Qualità delle app per Android per le auto.

Per decidere se disegnare una mappa scura, puoi utilizzare CarContext.isDarkMode . Ogni volta che lo stato del tema scuro cambia, ricevi una chiamata a Session.onCarConfigurationChanged

Consentire agli utenti di interagire con la mappa

Quando utilizzi i seguenti modelli, puoi aggiungere supporto per l'interazione degli utenti con le mappe che disegni, ad esempio consentendo loro di vedere diverse parti di una mappa 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)

Implementa callback di interattività

Interfaccia di SurfaceCallback dispone di diversi metodi di callback che puoi implementare per aggiungere interattività alle mappe create con i modelli della sezione precedente:

Interazione SurfaceCallback metodo Supportato dal livello API Car App
Tocca onClick 5
Pizzica per eseguire lo zoom onScale 2
Trascinamento con un solo tocco onScroll 2
Scorrimento single-touch onFling 2
Tocca due volte onScale (con fattore di scala determinato dall'host del modello) 2
Spinta rotatoria in modalità Panoramica onScroll (con il fattore di distanza determinato dall'host del modello) 2

Aggiungi una barra delle azioni sulla mappa

Questi modelli possono avere una barra delle azioni sulla mappa per le azioni relative alla mappa, come aumentare e diminuire lo zoom, ricentrare, visualizzare una bussola e altre azioni scegliere di visualizzare. La barra delle azioni sulla mappa può avere fino a quattro pulsanti con le sole icone che possono essere aggiornati senza influire sulla profondità dell'attività. Si nasconde in stato di inattività e viene visualizzato di nuovo in stato attivo.

Per ricevere i callback per l'interattività della mappa: deve aggiungere un pulsante Action.PAN nella barra delle azioni della mappa. Quando l'utente il pulsante Panoramica, l'host attiva la modalità Panoramica, come descritto .

Se la tua app omette Action.PAN nella barra delle azioni della mappa, non riceve l'input dell'utente SurfaceCallback e l'host chiude tutti quelli attivati in precedenza modalità pan.

Su un touchscreen, il pulsante per la panoramica non viene visualizzato.

Informazioni sulla modalità Panoramica

In modalità panoramica, l'host del modello traduce l'input dell'utente da quello non touch come controller rotativi e touchpad, al computer SurfaceCallback metodi. Rispondere all'azione dell'utente per attivare o uscire dalla modalità panoramica con setPanModeListener in NavigationTemplate.Builder. L'organizzatore può nascondere altre UI 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

L'app può rispondere all'input utente trasmettendo gli ascoltatori appropriati alla e modelli che le supportano. Il seguente snippet mostra come creare un Action modello 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 app per navigazione predefinita per auto utilizzando 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 ulteriori dettagli su come avviare le app, incluso il formato del Per intent ACTION_NAVIGATE, consulta l'articolo Avviare un'app per auto con un intent .

Alcune azioni, ad esempio quelle che richiedono all'utente di continuare sui dispositivi mobili sono consentite solo quando l'auto è parcheggiata. Puoi utilizzare lo ParkedOnlyOnClickListener per implementare queste azioni. Se l'auto non è parcheggiata, l'host visualizza un che indica all'utente che l'azione non è consentita in questo caso. Se l'auto è parcheggiato, il codice viene eseguito normalmente. Il seguente snippet mostra come usa 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 soltanto se vengono estese con CarAppExtender Alcuni attributi delle notifiche, come titolo dei contenuti, testo, icona e azioni, può essere impostato in CarAppExtender, sostituendo gli attributi della notifica quando vengono visualizzati sullo schermo dell'auto.

Il seguente snippet mostra come inviare una notifica allo schermo dell'auto che visualizza un titolo diverso da quello mostrato 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 interessare le seguenti parti dell'interfaccia utente:

  • All'utente potrebbe essere visualizzata una notifica di avviso (HUN).
  • È possibile aggiungere una voce nel centro notifiche, facoltativamente con un badge visibile sul binario.
  • Per le app di navigazione, la notifica può essere visualizzata nel widget ferroviario come descritti in Notifiche passo passo.
di Gemini Advanced.

Puoi scegliere come configurare le notifiche dell'app in modo che abbiano effetto su ogni tali elementi dell'interfaccia utente utilizzando la priorità della notifica, come descritto nel CarAppExtender documentazione.

Se NotificationCompat.Builder.setOnlyAlertOnce viene richiamata con il valore true, una notifica ad alta priorità viene visualizzata HUN solo una volta.

Per ulteriori informazioni su come progettare le notifiche dell'app dell'auto, vedi le Guida di Google Design for Driving Notifiche.

Mostra toast

La tua app può visualizzare un toast 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 restrizioni, ad esempio posizione: le regole standard di Android autorizzazioni . Per richiedere un'autorizzazione, puoi utilizzare CarContext.requestPermissions() .

Il vantaggio di usare CarContext.requestPermissions(), anziché utilizzare API Android standard, è che non ti serve avviare Activity la finestra di dialogo per creare le autorizzazioni. Inoltre, puoi utilizzare lo stesso codice Android Auto e Android Automotive OS, invece di dover creare che dipendono dalla piattaforma.

Applicare uno stile alla finestra di dialogo delle autorizzazioni su Android Auto

Su Android Auto, sullo smartphone viene visualizzata la finestra di dialogo delle autorizzazioni per l'utente. Per impostazione predefinita, non ci sarà alcuno sfondo dietro la finestra di dialogo. Per impostare un'istanza sullo sfondo, dichiara un tema dell'app per auto nel AndroidManifest.xml e imposta l'attributo carPermissionActivityLayout per il tema dell'app della tua 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 CarContext.startCarApp per eseguire una delle seguenti azioni:

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 wrapping di un elemento esplicita intenzione all'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());

L'app deve inoltre dichiarare BroadcastReceiver, ovvero richiamati per elaborare l'intent quando l'utente seleziona l'azione nella dell'interfaccia di notifica CarContext.startCarApp con un intent che includa l'URI dei 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, Session.onNewIntent nella tua app gestisce questo intent spostando la schermata di prenotazione del parcheggio nell'elenco, 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, consulta la sezione Mostra notifiche informazioni su come gestire le notifiche per l'app dell'auto.

Limitazioni relative al modello

L'host limita a un massimo il numero di modelli da visualizzare per una determinata attività su cinque, di cui l'ultimo modello deve essere di uno dei seguenti tipi:

Tieni presente che questo limite si applica al numero di modelli, non al numero di modelli, Screen istanze nello stack. Per Ad esempio, se un'app invia due modelli nella schermata A e poi sposta lo schermo B, ora può inviare altri tre modelli. In alternativa, se ogni schermata è strutturata per inviare un singolo modello, l'app può eseguire il push di cinque istanze di schermata Pila ScreenManager.

Esistono casi speciali per queste restrizioni: il modello viene aggiornato e viceversa operazioni di ripristino dei dati di fabbrica.

Aggiornamenti del modello

Alcuni aggiornamenti dei contenuti non concorrono al raggiungimento del limite di 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 conteggiato nella quota. Ad esempio, aggiornare lo stato di attivazione/disattivazione di una riga in una ListTemplate non conta rispetto alla quota. Per saperne di più, consulta la documentazione dei singoli modelli quali tipi di aggiornamenti dei contenuti possono essere considerati aggiornamenti.

Operazioni dorsali

Per attivare i flussi secondari all'interno di un'attività, l'host rileva quando un'app sta aprendo una Screen dallo stack ScreenManager e aggiornamenti la quota rimanente in base al numero di modelli usati dall'app al contrario.

Ad esempio, se l'app invia due modelli nella schermata A, poi invia schermata B e invia altri due modelli, l'app ha una quota rimanente. Se l'app torna alla schermata A, l'host reimposta la quota a tre, l'app è passata indietro di due modelli.

Tieni presente che, quando apri di nuovo una schermata, un'app deve inviare un modello che dello stesso tipo dell'ultimo inviato dalla schermata. Invio di qualsiasi altro utente il tipo di modello causa un errore. Tuttavia, finché il tipo rimane durante un'operazione di ritorno, un'app può modificare liberamente i contenuti senza influire sulla quota.

Operazioni di reimpostazione

Alcuni modelli hanno una semantica speciale che indica la fine di un'attività. Per Ad esempio, NavigationTemplate è una visualizzazione che dovrebbe rimanere sullo schermo e aggiornata con nuove istruzioni passo passo per il consumo dell'utente. Quando raggiunge uno di questi modelli, l'host reimposta la quota, trattando il modello come se è 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 una reimpostazione sull'host.

Se l'organizzatore riceve l'intenzione di avviare l'app da un'azione di notifica o da Avvio app, viene reimpostata anche la quota. Questo meccanismo consente a un'app iniziare un nuovo flusso di attività dalle notifiche e questo vale anche se un'app già associate e in primo piano.

Per ulteriori dettagli, consulta la sezione Visualizzare le notifiche su come visualizzare le notifiche dell'app nello schermo dell'auto. Consulta le Sezione Avviare un'app per auto con un intent per avere informazioni su come per avviare l'app da un'azione di notifica.

API Connection

Puoi stabilire se la tua app è installata su Android Auto o su Android Automotive OS utilizzando API CarConnection in per recuperare le informazioni di connessione in fase di esecuzione.

Ad esempio, nel file Session dell'app dell'auto, inizializza CarConnection e iscriviti agli aggiornamenti di LiveData:

Kotlin

CarConnection(carContext).type.observe(this, ::onConnectionStateUpdated)

Java

new CarConnection(getCarContext()).getType().observe(this, this::onConnectionStateUpdated);

Nell'osservatore, puoi quindi reagire ai cambiamenti nello stato di 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

Diverse auto possono consentire un numero diverso di Item istanze da mostrare l'utente alla volta. Utilizza la ConstraintManager per controllare il limite per i contenuti in fase di runtime e impostare il numero appropriato di elementi nei tuoi modelli.

Inizia ricevendo un ConstraintManager da CarContext:

Kotlin

val manager = carContext.getCarService(ConstraintManager::class.java)

Java

ConstraintManager manager = getCarContext().getCarService(ConstraintManager.class);

Puoi quindi eseguire una query sull'oggetto ConstraintManager recuperato per trovare la query limiti dei contenuti. Ad esempio, per ottenere il numero di elementi che possono essere visualizzati una griglia, richiama 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);

Aggiungi un flusso di accesso

Se la tua app offre agli utenti un'esperienza di accesso, puoi utilizzare modelli come SignInTemplate e LongMessageTemplate con Car App API di livello 2 e superiore per gestire l'accesso all'app nel all'unità principale dell'auto.

Per creare un SignInTemplate, definisci un SignInMethod. L'auto Al momento, la libreria di app supporta i seguenti metodi di accesso:

  • InputSignInMethod per l'accesso con nome utente/password.
  • PinSignInMethod per l'accesso con PIN, dove l'utente collega il proprio account dal telefono usando il PIN visualizzato sull'unità principale.
  • ProviderSignInMethod per l'accesso del fornitore, ad esempio Accedi con Google e Un tocco.
  • QRCodeSignInMethod per l'accesso con codice QR, dove l'utente scansiona un codice QR per completare l'accesso sul loro telefono. Questa funzionalità è disponibile con API Car di livello 4 e successivi.

Ad esempio, per implementare un modello che raccoglie la password dell'utente, inizia con la creazione di una 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.
    }
};

È richiesto 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 con autenticazione devono utilizzare AccountManager per i seguenti motivi:

  • Esperienza utente migliore e facilità di gestione dell'account. Gli utenti possono gestire facilmente tutti i loro account dal menu degli account nelle impostazioni di sistema, compreso e uscire.
  • "Ospite" : poiché le auto sono dispositivi condivisi, gli OEM possono esperienze degli ospiti all'interno del veicolo, per le quali non è possibile aggiungere account.

Aggiungi varianti della stringa di testo

Gli schermi delle auto di dimensioni diverse possono mostrare testo diverso. Con API Car App livello 2 e superiore, puoi specificare più varianti di una stringa di testo al meglio si adattano allo schermo. Per sapere dove vengono accettate le varianti di testo, cerca i modelli e che richiedono un elemento CarText.

Puoi aggiungere varianti della stringa di testo a un CarText con il 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 CarText, ad esempio, come testo principale di un GridItem

Kotlin

GridItem.Builder()
    .addTitle(itemTitle)
    ...
    .build()

Java

new GridItem.Builder()
    .addTitle(itemTitle)
    ...
    build();

Aggiungi stringhe in ordine, dalla più lunga alla meno preferita, ad esempio dalla più lunga alla più lunga più breve. L'host sceglie la stringa di lunghezza appropriata in base al di spazio disponibile sullo schermo dell'auto.

Aggiungi elementi CarIcon incorporati per le righe

Puoi aggiungere icone incorporate nel testo per arricchire l'aspetto visivo della tua app utilizzando CarIconSpan Consulta la documentazione per CarIconSpan.create per ulteriori informazioni sulla creazione di questi intervalli. Consulta Spantastico applicazione degli stili del testo con Intervalli per una panoramica del funzionamento dello stile del testo con le sezioni.

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 per hardware per auto

A partire dal livello 3 dell'API Car App, la libreria di app auto dispone di API che per accedere alle proprietà e ai sensori dei veicoli.

Requisiti

Per utilizzare le API con Android Auto, inizia aggiungendo una dipendenza androidx.car.app:app-projected al file build.gradle per il tuo Android Modulo Auto. Per Android Automotive OS, aggiungi una dipendenza androidx.car.app:app-automotive al file build.gradle per il tuo Android Modulo sistema operativo Automotive.

Inoltre, nel file AndroidManifest.xml devi: dichiarare le autorizzazioni pertinenti necessarie per richiedere i dati dell'auto che vuoi usare. Tieni presente che anche queste autorizzazioni devono essere concesso dall'utente. Puoi utilizzare lo lo stesso codice su Android Auto e Android Automotive OS, anziché che dover creare flussi dipendenti dalla piattaforma. Tuttavia, le autorizzazioni necessarie sono diverse.

Info auto

In questa tabella vengono descritte le proprietà visualizzate API di CarInfo e autorizzazioni che devi richiedere per utilizzarle:

Metodi Proprietà Autorizzazioni di Android Auto Autorizzazioni di Android Automotive OS Supportato 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 pedaggio, tipo di carta pedaggio 3
addEnergyLevelListener
removeEnergyLevelListener
Livello batteria, livello carburante, livello 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à non elaborata, velocità del display (visualizzate sul display del cluster dell'auto) com.google.android.gms.permission.CAR_SPEED android.car.permission.CAR_SPEED,
android.car.permission.READ_CAR_DISPLAY_UNITS
3
addMileageListener
removeMileageListener
Distanza del contachilometri com.google.android.gms.permission.CAR_MILEAGE Su Android Automotive OS, questi dati non sono disponibili per le app installate dal Play Store. 3

Ad esempio, per ottenere l'intervallo rimanente, crea un'istanza di CarInfo oggetto, poi 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 messaggio di errore, controlla stato di il valore richiesto per comprendere meglio perché i dati richiesti potrebbero non possono essere recuperati. Consulta le documentazione di riferimento per la definizione completa della classe CarInfo.

Sensori auto

Il corso CarSensors consente di accedere all'accelerometro, al giroscopio, alla bussola e dati sulla posizione. La disponibilità di questi valori può dipendere OEM. Il formato dei dati dell'accelerometro, del giroscopio e della bussola è lo stesso che otterresti 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 dall'auto, devi inoltre dichiarare e richiedere il Autorizzazione android.permission.ACCESS_FINE_LOCATION.

Test

Per simulare i dati dei sensori durante i test su Android Auto, consulta le Sensori e Sensori configurazione Guida all'unità principale desktop. Per simulare i dati dei sensori durante i test su Android Automotive OS, consulta la sezione Emula hardware di Android Guida dell'emulatore del sistema operativo Automotive.

Ciclo di vita di CarAppService, della sessione e dello schermo

Le Session e Le classi Screen implementano LifecycleOwner. Come l'utente interagisce con l'app e con gli oggetti Session e Screen ciclo di vita vengono richiamati, come illustrato nei diagrammi di seguito.

I cicli di vita di un servizio CarAppService e di una sessione

Figura 1. Il ciclo di vita di Session.

Per i dettagli completi, consulta la documentazione Session.getLifecycle .

Il ciclo di vita di una schermata

Figura 2. Il ciclo di vita di Screen.

Per informazioni dettagliate, consulta la documentazione relativa Screen.getLifecycle.

Registra dal microfono dell'auto

Se utilizzi CarAppService e API CarAudioRecord, puoi concedere alla tua app l'accesso al microfono dell'auto dell'utente. Gli utenti devono fornire l'autorizzazione dell'app ad accedere al microfono dell'auto. La tua app può registrare elaborare l'input dell'utente all'interno dell'app.

Autorizzazione alla registrazione

Prima di registrare qualsiasi audio, devi dichiarare l'autorizzazione a registrare nel tuo AndroidManifest.xml e richiedi che l'utente lo conceda.

<manifest ...>
   ...
   <uses-permission android:name="android.permission.RECORD_AUDIO" />
   ...
</manifest>

Devi richiedere l'autorizzazione per registrare in fase di runtime. Consulta la richiesta autorizzazioni per maggiori dettagli su come richiedere autorizzazione nell'app dell'auto.

Registra l'audio

Dopo che l'utente concede l'autorizzazione alla registrazione, puoi registrare l'audio ed elaborare l'audio. 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 l'audio attiva su assicurarti che tutti i contenuti multimediali in corso vengano interrotti. Se perdi il focus audio, interrompi la registrazione.

Ecco un esempio di come acquisire il focus 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

Il test di Android for Cars La libreria fornisce informazioni ausiliarie che puoi utilizzare per convalidare il comportamento della tua app in un ambiente di test. Ad esempio, SessionController consente di simulare una connessione all'host e verificare che sia Screen e Template vengono creati restituito.

Consulta le Campioni per esempi di utilizzo.

Segnalare un problema relativo alla libreria di app Android for Cars

Se rilevi un problema con la libreria, segnalalo utilizzando il Google Issue Tracker. Assicurati di compilare tutte le informazioni richieste nel modello di problema.

Crea un nuovo numero

Prima di inviare un nuovo numero, controlla se è elencato nell'uscita della raccolta note o segnalati nell'elenco dei problemi. Puoi iscriverti e votare per i problemi tramite facendo clic sulla stella per un problema nel tracker. Per ulteriori informazioni, vedi Abbonarsi a un problema.