Sviluppo di app

Per implementare un'applicazione per le interazioni vocali (VIA), devi completare questi passaggi:

  1. Crea uno scheletro VIA.
  2. (Facoltativo) Implementa un flusso di configurazione/accesso.
  3. (Facoltativo) Implementa una schermata Impostazioni.
  4. Dichiara le autorizzazioni richieste nel file manifest.
  5. Implementa un'interfaccia utente per il riquadro vocale.
  6. Implementare il riconoscimento vocale (deve includere l'implementazione dell'API RecognitionService).
  7. Implementa l'enunciato (facoltativamente puoi implementare l'API TextToSpeech).
  8. Implementa il completamento dei comandi. Visualizza questi contenuti in Esecuzione dei comandi.

Le seguenti sezioni descrivono come completare ogni passaggio indicato sopra.

Crea uno scheletro VIA

Manifest

Viene rilevata un'app con Interazione vocale quando: incluse nel manifest:

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myvoicecontrol">
    ...

  <application ... >
    <service android:name=".MyInteractionService"
        android:label="@string/app_name"
        android:permission="android.permission.BIND_VOICE_INTERACTION"
        android:process=":interactor">
      <meta-data
          android:name="android.voice_interaction"
          android:resource="@xml/interaction_service" />
      <intent-filter>
        <action android:name=
          "android.service.voice.VoiceInteractionService" />
      </intent-filter>
    </service>
  </application>
</manifest>

In questo esempio:

  • Le ViA devono esporre un servizio che estenda VoiceInteractionService, con un filtro per intent per l'azione VoiceInteractionService.SERVICE_INTERFACE ("android.service.voice.VoiceInteractionService").
  • Questo servizio deve disporre dell'autorizzazione di firma di sistema di BIND_VOICE_INTERACTION.
  • Questo servizio deve includere un file di metadati android.voice_interaction per contenere quanto segue:

    res/xml/interaction_service.xml

    <voice-interaction-service
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:sessionService=
          "com.example.MyInteractionSessionService"
        android:recognitionService=
          "com.example.MyRecognitionService"
        android:settingsActivity=
          "com.example.MySettingsActivity"
        android:supportsAssist="true"
        android:supportsLaunchVoiceAssistFromKeyguard="true"
        android:supportsLocalInteraction="true" />
    

Per maggiori dettagli su ciascun campo, vedi R.styleable#VoiceInteractionService. Dato che tutti i VIA sono anche servizi di riconoscimento vocale, devi anche includi quanto segue nel file manifest:

AndroidManifest.xml

<manifest ...>
  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  <application ...>
    ...
    <service android:name=".RecognitionService" ...>
      <intent-filter>
        <action android:name="android.speech.RecognitionService" />
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
      <meta-data
        android:name="android.speech"
        android:resource="@xml/recognition_service" />
    </service>
  </application>
</manifest>

I servizi di riconoscimento vocale richiedono anche i seguenti metadati:

res/xml/recognition_service.xml

<recognition-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:settingsActivity="com.example.MyRecognizerSettingsActivity" />

VoiceInteractionService, VoiceInteractionSessionService e VoiceInteractionSession

Il seguente diagramma illustra il ciclo di vita di ciascuna di queste entità:

Cicli di vita

Figura 1. Cicli di vita

Come indicato in precedenza, VoiceInteractionService è il punto di ingresso in un VIA. Le principali responsabilità di questo servizio sono:

  • Inizializza tutti i processi che devono essere mantenuti in esecuzione per tutto il tempo questo VIA è quello attivo. Ad esempio, rilevamento hotword.
  • Consente di segnalare azioni vocali supportate (vedi Tocca per leggere dell'Assistente vocale).
  • Avvia sessioni di interazione vocale dalla schermata di blocco (keyguard).

Nella sua forma più semplice, un'implementazione VoiceInteractionService sembra nel seguente modo:

public class MyVoiceInteractionService extends VoiceInteractionService {
    private static final List<String> SUPPORTED_VOICE_ACTIONS =
        Arrays.asList(
            CarVoiceInteractionSession.VOICE_ACTION_READ_NOTIFICATION,
            CarVoiceInteractionSession.VOICE_ACTION_REPLY_NOTIFICATION,
            CarVoiceInteractionSession.VOICE_ACTION_HANDLE_EXCEPTION
    );

    @Override
    public void onReady() {
        super.onReady();
        // TODO: Setup hotword detector
    }

    @NonNull
    @Override
    public Set<String> onGetSupportedVoiceActions(
            @NonNull Set<String> voiceActions) {
        Set<String> result = new HashSet<>(voiceActions);
        result.retainAll(SUPPORTED_VOICE_ACTIONS);
        return result;
    }
    ...
}

L'implementazione di VoiceInteractionService#onGetSupportedVoiceActions() è necessari per gestire Assistente vocale Tocca per leggere. Il sistema utilizza un VoiceInteractionSessionService per creare e interagire con VoiceInteractionSession. Ha una sola responsabilità, per avviare nuove sessioni quando richiesto.

public class MyVoiceInteractionSessionService extends VoiceInteractionSessionService {
    @Override
    public VoiceInteractionSession onNewSession(Bundle args) {
        return new MyVoiceInteractionSession(this);
    }
}

Infine, VoiceInteractionSession è il momento in cui si svolge la maggior parte del lavoro che sarebbe stato fatto. Un'istanza di una singola sessione può essere riutilizzata per completare le interazioni degli utenti. In AAOS esiste un helper CarVoiceInteractionSession , contribuendo a implementare alcune funzionalità esclusive del settore automobilistico.

public class MyVoiceInteractionSession extends CarVoiceInteractionSession {

    public InteractionSession(Context context) {
        super(context);
    }

    @Override
    protected void onShow(String action, Bundle args, int showFlags) {
        closeSystemDialogs();
        // TODO: Unhide UI and update UI state
        // TODO: Start processing audio input
    }
    ...
}

VoiceInteractionSession ha un'ampia gamma di metodi di callback spiegate nelle sezioni seguenti. consulta la documentazione di VoiceInteractionSession per un elenco completo.

Implementare un flusso di configurazione/accesso

La configurazione e l'accesso possono avvenire nei seguenti casi:

  • Durante le operazioni preliminari del dispositivo (configurazione guidata).
  • Durante lo scambio del servizio di interazione vocale (Impostazioni).
  • Al primo avvio, quando l'app è selezionata.

Per maggiori dettagli sull'esperienza utente consigliata e sulle indicazioni visive, consulta Assistenti precaricati: indicazioni UX.

Configurazione durante lo scambio del servizio vocale

È sempre possibile che l'utente selezioni una VIA che non è stata configurato. Ciò può accadere perché:

  • L'utente ha saltato completamente la configurazione guidata o l'utente ha saltato la voce passaggio per la configurazione dell'interazione.
  • L'utente ha selezionato una VIA diversa da quella configurata durante il dispositivo l'onboarding.

In ogni caso, un VoiceInteractionService ha diversi modi per incoraggiare l'utente per completare la configurazione:

  • Promemoria di notifica.
  • Risposta vocale automatica quando l'utente prova a utilizzarla.

Nota: sconsigliamo vivamente di presentare un flusso di configurazione VIA senza una richiesta esplicita dell'utente. Ciò significa che le VM dovrebbero evitare visualizzazione di contenuti nell'interfaccia utente durante l'avvio del dispositivo o a seguito di un cambio dell'utente sblocca.

Promemoria notifica

Un promemoria di notifica è un modo non invasivo per indicare la necessità di una configurazione, e fornire agli utenti l'invito ad accedere alla configurazione dell'assistente flusso di lavoro.

Promemoria notifica

Figura 2. Promemoria notifica

Ecco come funziona questo flusso:

Flusso di promemoria delle notifiche

Figura 3. Flusso di promemoria delle notifiche

Risposta vocale

Questo è il flusso più semplice da implementare, con l'avvio di un'espressione un callback VoiceInteractionSession#onShow(), che spiega all'utente cosa deve essere completata, quindi chiedi (se la configurazione è consentita in base allo stato di restrizione UX) se il cliente vuole avviare il flusso di configurazione. Se al momento non è possibile effettuare la configurazione, spiega: anche in questa situazione.

Configurazione al primo utilizzo

L'utente può sempre attivare una VIA che non è stata configurato. In questi casi:

  1. Comunica a voce l'utente in merito alla situazione (ad esempio, "Per funzionare correttamente, Devi completare alcuni passaggi ... ").
  2. Se il motore delle limitazioni UX lo consente (vedi UX_RESTRICTIONS_NO_CONFIGURAZIONE), chiedi all'utente se vuole avviare la processo di configurazione e apri la schermata Impostazioni per il VIA.
  3. In caso contrario, ad esempio se l'utente sta guidando, lascia una notifica in modo che possa fai clic sull'opzione quando puoi farlo in sicurezza.

Creare schermate di configurazione per l'interazione vocale

Le schermate di configurazione e di accesso devono essere sviluppate come normali attività. Consulta le le linee guida visive e relative all'esperienza utente per lo sviluppo della UI in Assistenti precaricati: indicazioni UX.

Linee guida generali:

  • Le Via devono consentire agli utenti di interrompere e riprendere la configurazione in qualsiasi momento.
  • La configurazione non deve essere consentita se è attiva la limitazione di UX_RESTRICTIONS_NO_SETUP. Per maggiori dettagli, vedi Linee guida sulla distrazione per chi guida.
  • Le schermate di configurazione devono corrispondere al sistema di progettazione di ciascun veicolo. Schermata generale layout, icone, colori e altri aspetti devono essere coerenti con il resto dell'interfaccia utente. Consulta Personalizzazione per maggiori dettagli.

Implementazione di una schermata delle impostazioni

Integrazione delle impostazioni

Figura 4. Integrazione delle impostazioni

Le schermate delle impostazioni sono le normali attività di Android. Se implementato, il relativo punto di ingresso deve essere dichiarato in res/xml/interaction_service.xml nell'ambito della VIA (vedi manifest). La sezione Impostazioni è un buon posto per continuare la configurazione e l'accesso (se l'utente non ha completato ) oppure offrire un'opzione per uscire o cambiare utente, se necessario. Simile alla configurazione descritte sopra, queste schermate devono:

  • Dare l'opzione per tornare alla schermata precedente nell'elenco filtri (ad esempio, Impostazioni auto).
  • Non è consentita durante la guida. Per maggiori dettagli, consulta le linee guida sulla distrazione del conducente.
  • Abbina ogni sistema di progettazione del veicolo. Per maggiori dettagli, vedi Personalizzazione.

Dichiara le autorizzazioni richieste nel file manifest

Le autorizzazioni richieste da un VIA possono essere suddivise in tre categorie:

  • Autorizzazioni di firma del sistema. Queste sono le autorizzazioni concessa soltanto agli APK preinstallati firmati dal sistema. Gli utenti non possono concedere queste autorizzazioni, solo gli OEM possono concederle durante la creazione delle immagini di sistema. Per ulteriori informazioni su come ottenere le autorizzazioni di firma, vedi Concedere autorizzazioni con privilegi di sistema.
  • Autorizzazioni pericolose. Queste sono le autorizzazioni che un utente deve concedere usando la finestra di dialogo PermissionsController. Gli OEM possono pre-concessione alcuni di questi le autorizzazioni per il servizio VoiceInteractionService predefinito. Ma dato che questa impostazione potrebbero cambiare da dispositivo a dispositivo, le app devono poter richiedere questi le autorizzazioni quando necessario.
  • Altre autorizzazioni. Queste sono tutte le altre autorizzazioni non richiedono l'intervento dell'utente. Queste autorizzazioni vengono concesse automaticamente dal sistema.

Considerato quanto sopra, la seguente sezione si concentra solo sulla richiesta autorizzazioni pericolose. Le autorizzazioni devono essere richieste solo mentre l'utente nelle schermate di accesso o di impostazione.

Se l'app non dispone delle autorizzazioni necessarie per funzionare, la procedura consigliata è quella di utilizzare un enunciato vocale per spiegare la situazione al all'utente e una notifica per fornire un'invito che l'utente può utilizzare per torna alle schermate delle impostazioni di VIA. Per maggiori dettagli, vedi 1. Promemoria di notifica.

Richiedi le autorizzazioni nella schermata delle impostazioni

Le autorizzazioni pericolose vengono richieste utilizzando il normale metodo ActivityCompat#requestPermission() (o equivalente). Per maggiori dettagli su come richiedere le autorizzazioni, consulta Richiedi autorizzazioni app.

Richiedi autorizzazioni

Figura 5. Richiedi autorizzazioni

Autorizzazione listener di notifiche

Per implementare il flusso TTR, i VIA devono essere designati come listener di notifiche. Non si tratta di un'autorizzazione a sé stante, ma di un'autorizzazione che consente al sistema di inviare notifiche agli utenti e ascoltatori. Per sapere se alla VIA è stato concesso l'accesso a queste informazioni, le app possono:

Se questo accesso non viene concesso in anticipo, la VIA deve indirizzare l'utente alla Sezione Accesso alle notifiche di Impostazioni auto, utilizzando una combinazione di frasi e notifiche. Il seguente codice può essere usato per aprire la sezione appropriata del app impostazioni:

private void requestNotificationListenerAccess() {
    Intent intent = new Intent(Settings
        .ACTION_NOTIFICATION_LISTENER_SETTINGS);
    intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
    startActivity(intent);
}

Implementa un'interfaccia utente per il riquadro vocale

Quando un VoiceInteractionSession riceve una richiamata di onShow(), può presentare una UI di riquadro vocale. Per le linee guida relative alle immagini e all'esperienza utente relative all'implementazione della finestra vocale,consulta: Assistenti precaricati: indicazioni UX.

Visualizzazione della finestra di conversazione

Figura 6. Visualizzazione della finestra di conversazione

Esistono due opzioni per implementare questa UI:

  • Esegui l'override di VoiceInteractionSession#onCreateContentView()
  • Lancia un'attività utilizzando VoiceInteractionSession#startAssistantActivity()

Utilizzare onCreateContentView()

Questo è il modo predefinito per presentare una finestra di conversazione. VoiceInteractionSession una classe base crea una finestra e gestisce il suo ciclo di vita per tutto il tempo mediante una voce la sessione è attiva. Le app devono sostituire VoiceInteractionSession#onCreateContentView() e restituire una visualizzazione allegata a quella finestra non appena la sessione è stato creato. Questa visualizzazione inizialmente dovrebbe essere invisibile. Quando inizia un'interazione vocale, questa vista deve essere resa visibile su VoiceInteractionSession#onShow() e poi di nuovo invisibile il giorno VoiceInteractionSession#onHide().

public class MyVoiceInteractionSession extends CarVoiceInteractionSession {
    private View mVoicePlate;
    …

    @Override
    public View onCreateContentView() {
        mVoicePlate = inflater.inflate(R.layout.voice_plate, null);
        …
   }

    @Override
    protected void onShow(String action, Bundle args, int showFlags) {
        // TODO: Update UI state to "listening"
        mVoicePlate.setVisibility(View.VISIBLE);
    }

    @Override
    public void onHide() {
        mVoicePlate.setVisibility(View.GONE);
    }
    …
}

Quando utilizzi questo metodo, potrebbe essere opportuno modificare VoiceInteractionSession#onComputeInsets() per tenere conto delle aree oscurate della UI.

Usa startAssistantActivity()

In questo caso, VoiceInteractionSession delega la gestione della voce a una normale attività. Quando viene utilizzata questa opzione, viene applicata una VoiceInteractionSession deve disattivare la creazione della relativa finestra di contenuto predefinita (vedi Utilizzo di onCreateContentView()) nella onPrepareShow() di Google. Alle ore VoiceInteractionSession#onShow(), la sessione avvierà la voce attività durante una targa utilizzando VoiceInteractionSession#startAssistantActivity(). Questo avvia la UI con le impostazioni della finestra e i flag di attività corretti.

public class MyVoiceInteractionSession extends CarVoiceInteractionSession {
    …

    @Override
    public void onPrepareShow(Bundle args, int showFlags) {
        super.onPrepareShow(args, showFlags);
        setUiEnabled(false);
    }

    @Override
    protected void onShow(String action, Bundle args, int showFlags) {
        closeSystemDialogs();
        Intent intent = new Intent(getContext(), VoicePlateActivity.class);
        intent.putExtra(VoicePlateActivity.EXTRA_ACTION, action);
        intent.putExtra(VoicePlateActivity.EXTRA_ARGS, args);
        startAssistantActivity(intent);
    }

    …
}

Per mantenere una comunicazione tra questa attività e il VoiceInteractionSession, un insieme di intent interni o di associazione di servizi potrebbe essere obbligatorio. Ad esempio, quando viene richiamato VoiceInteractionSession#onHide(), il parametro La sessione deve essere in grado di passare questa richiesta all'attività.

Importante: Nel settore auto e motori, vengono visualizzate solo attività o attività elencate nella "lista consentita" dell'UXR possono essere visualizzati alla guida. Questo vale per le attività iniziate con VoiceInteractionSession#startAssistantActivity(). Ricorda di prestare attenzione annota la tua attività con <meta-data android:name="distractionOptimized" android:value="true"/> o includi questo attività nella chiave systemActivityWhitelist di /packages/services/Car/service/res/values/config.xml . Per ulteriori informazioni, vedi Driver Linee guida sulla distrazione.

Implementare il riconoscimento vocale

In questa sezione imparerai a implementare il riconoscimento vocale tramite l'app e riconoscimento delle hotword. Una hotword è una parola di attivazione utilizzata per avviare una nuova query o un'azione vocale. Ad esempio, "Hey Google" o "Hey Google".

Rilevamento hotword DSP

Android fornisce l'accesso a un rilevatore hotword sempre attivo a livello di DSP di AlwaysOnHotwordDetector. per implementare il rilevamento della hotword con CPU ridotta. L'utilizzo di questa funzionalità è diviso in due parti:

  • Creazione di un'istanza di un AlwaysOnHotwordDetector.
  • Registrazione di un modello audio per il rilevamento della hotword.

L'implementazione di VoiceInteractionService può creare un rilevatore hotword utilizzando VoiceInteractionService#createAlwaysOnHotwordDetector(), passando una frase chiave e una lingua da usare per il rilevamento. Di conseguenza, l'app riceve un onAvailabilityChanged() con uno dei seguenti valori possibili:

  • STATE_HARDWARE_UNAVAILABLE. La funzionalità DSP non è disponibile nella dispositivo. In questo caso, viene utilizzato il rilevamento hotword software.
  • STATE_HARDWARE_UNSUPPORTED. Il supporto DSP non è disponibile in generale, ma Il DSP non supporta la combinazione di frase chiave e lingua. L'app può scegliere di utilizzare Rilevamento hotword.
  • STATE_HARDWARE_ENROLLED. Il rilevamento hotword è pronto e può essere avviato chiamando il metodo startRecognition().
  • STATE_HARDWARE_UNENROLLED. Un modello audio per la frase chiave richiesta non è disponibile, ma è possibile registrarsi.

La registrazione dei modelli audio per il rilevamento della hotword può essere effettuata utilizzando IVoiceInteractionManagerService#updateKeyphraseSoundModel(). Nel sistema possono essere registrati più modelli contemporaneamente, ma solo uno modello è associato a un AlwaysOnHotwordDetector. Il rilevamento della hotword DSP potrebbe non essere disponibile su tutti i dispositivi. Sviluppatori VIA dovrebbe controllare le funzionalità hardware utilizzando getDspModuleProperties() . Per vedere il codice di esempio su come registrare i modelli audio, visita la pagina VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java. Consulta Acquisizione simultanea per informazioni riconoscimento hotword simultaneo.

Rilevamento hotword software

Come indicato sopra, il rilevamento della hotword DSP potrebbe non essere disponibile in tutti (ad esempio, l'emulatore Android non fornisce l'emulazione DSP). In questo caso, il riconoscimento vocale tramite software è l'unica alternativa. Per evitare interferenze con altri alle app che potrebbero richiedere l'accesso al microfono, i VIA devono accedere all'input audio utilizzando:

Entrambe queste costanti sono @hide e disponibili solo per le app in bundle.

Gestisci l'input audio e il riconoscimento vocale

L'input audio verrebbe implementato utilizzando la classe MediaRecorder. Per ulteriori informazioni su come utilizzare questa API, consulta MediaRecorder Panoramica. Anche i servizi di interazione vocale dovrebbero essere RecognitionService implementazioni di classe. Qualsiasi app nel sistema che richiede il riconoscimento vocale utilizza per accedere a questa funzionalità. Per eseguire il riconoscimento vocale e avere accesso al microfono, ViA deve contenere android.permission.RECORD_AUDIO. App che accedono a un RecognitionService anche l'implementazione deve avere questa autorizzazione.

Prima di Android 10, l'accesso al microfono veniva concesso a una sola app alla volta orario (ad eccezione del rilevamento della hotword, vedi sopra). A partire da Android 10, L'accesso al microfono può essere condiviso. Per ulteriori informazioni, consulta la sezione Condivisione Ingresso audio.

Accedi all'uscita audio

Quando la VIA è pronta a fornire risposte verbali, è importante segui queste linee guida: