Assistente vocale Tocca per leggere

Android Automotive considera il parlato come un componente fondamentale per interazioni sicure per gli utenti e uno dei modi più sicuri per interagire con il sistema operativo Android Automotive durante la guida. Di conseguenza, abbiamo ampliato API dell'assistente vocale Android (tra cui VoiceInteractionSession) per consentire agli assistenti vocali di eseguire attività per gli utenti che può essere difficile da raggiungere durante la guida.

Tocca per leggere consente agli assistenti vocali di leggere e rispondere ai messaggi su per conto dell'utente, quando quest'ultimo interagisce con le notifiche dei messaggi. Per fornire questa funzionalità, puoi integrare un assistente vocale con CarVoiceInteractionSession.

Nel settore auto e motori, le notifiche pubblicate nel Centro notifiche identificano come INBOX o INBOX_IN_GROUP (ad esempio, SMS) includono un Pulsante Riproduci. L'utente può fare clic su Riproduci per visualizzare l'assistente vocale legge la notifica ad alta voce e può rispondere con la voce, se lo desidera.

Notifica Tocca per leggere

Figura 1. Notifica Tocca per leggere con il pulsante Riproduci.

Integra con CarVoiceInteractionSession

Le sezioni successive descrivono come integrare un assistente vocale con CarVoiceInteractionSession.

Supporta le interazioni vocali

Le app che forniscono servizi di interazione vocale con l'auto devono si integrano con le interazioni vocali esistenti di Android. Per scoprire di più, vedi Assistente Google per Android (ad eccezione di VoiceInteractionSession). Mentre l'API per tutte le interazioni vocali rimangono gli stessi di quelli implementati sui dispositivi mobili, CarVoiceInteractionSession (descritto in Implementare CarVoiceInteractionSession) sostituisce VoiceInteractionSession. Per ulteriori informazioni, consulta queste pagine:

Implementare CarVoiceInteractionSession

CarVoiceInteractionSession espone API che puoi utilizzare per consentire agli assistenti vocali di leggere i messaggi ad alta voce e quindi rispondere ai messaggi per conto dell'utente.

La differenza principale tra CarVoiceInteractionSession e VoiceInteractionSession corso è che CarVoiceInteractionSession passa per l'azione in onShow in modo che l'assistente vocale possa rilevare il contesto della richiesta dell'utente non appena CarVoiceInteractionSession avvia una sessione. I parametri per onShow per ogni corso sono elencati nella seguente tabella:

Sessione CarVoiceInteraction Sessione VoiceInteraction
onShow richiede questi tre parametri:
  • args
  • showFlags
  • actions
onShow richiede questi due parametri:
  • args
  • showFlags

Modifiche in Android 10

A partire da Android 10, la piattaforma chiama VoiceInteractionService.onGetSupportedVoiceActions per rilevare le azioni supportate. L'assistente vocale esegue l'override e implementa VoiceInteractionService.onGetSupportedVoiceActions, come mostrato nell'esempio seguente:

public class MyInteractionService extends VoiceInteractionService {
    private static final List SUPPORTED_VOICE_ACTIONS = Arrays.asList(
        CarVoiceInteractionSession.VOICE_ACTION_READ_NOTIFICATION);

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

Le azioni valide sono descritte nella seguente tabella. Per maggiori dettagli su ogni azione, consulta Diagrammi di sequenza.

Azione Payload previsto Azione di interazione vocale prevista
VOICE_ACTION_READ_NOTIFICATION Leggi i messaggi all'utente e attiva il pulsante Contrassegna come letto in attesa. l'intent quando i messaggi vengono letti correttamente. Facoltativamente, puoi richiedere il per ricevere una risposta.
VOICE_ACTION_REPLY_NOTIFICATION Parcelable con chiave.
KEY_NOTIFICATION che mappa a StatusBarNotification.
Richiede android.permission.BIND_NOTIFICATION_LISTENER_SERVICE.
Chiedi all'utente di pronunciare il messaggio di risposta, inseriscilo nella RemoteInputReply dell'intent in sospeso, quindi attiva l'oggetto in attesa di intento.
VOICE_ACTION_HANDLE_EXCEPTION Stringa con chiave.
KEY_EXCEPTION che mappa a ExceptionValue (descritto in Valori delle eccezioni).
KEY_FALLBACK_ASSISTANT_ENABLED mappato a un valore booleano. Se il valore è true, l'assistente di riserva in grado di gestire la richiesta dell'utente. disattivata.
L'azione prevista da intraprendere per l'eccezione è definita nella sezione relativa all'eccezione.

Valori delle eccezioni

EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING indica all'assistente vocale che non dispone dell'autorizzazione Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE e di richiederla all'utente.

Richiedi l'autorizzazione del listener di notifiche

Se l'assistente vocale predefinito non ha il listener di notifiche l'autorizzazione, il parametro FallbackAssistant della piattaforma (se abilitato dal produttore del veicolo) potrebbe leggere il messaggio prima che venga attivato l'assistente vocale per richiedere l'autorizzazione. Per determinare se FallbackAssistant è abilitato e ha letto il messaggio, l'assistente vocale dovrebbe controllare KEY_FALLBACK_ASSISTANT_ENABLED Valore booleano nel payload.

La piattaforma consiglia all'assistente vocale di aggiungere una logica di limitazione della frequenza per il numero di volte in cui viene richiesta questa autorizzazione. In questo modo si rispetta l'utente che non concedere all'assistente vocale questa autorizzazione e preferisce la FallbackAssistant per leggere gli SMS ad alta voce. Richiesta di un l'utente deve richiedere l'autorizzazione ogni volta che preme Riproduci nella notifica di un messaggio può essere un'esperienza utente negativa. La piattaforma non impone limiti di frequenza per conto dell'assistente vocale.

Quando si richiede l'autorizzazione ad ascoltare le notifiche, l'assistente vocale deve usa CarUxRestrictionsManager per capire se un utente è parcheggiato o sta guidando. Se l'utente sta guidando, l'assistente vocale mostra una notifica che fornisce istruzioni su come concedere l'autorizzazione. In questo modo aiuta (e ricorda) all'utente di concedere l'autorizzazione quando è più sicuro.

Utilizzo di StatusBarNotification

StatusBarNotification passato con la lettura e la risposta le azioni vocali sono sempre in una notifica di messaggistica compatibile con l'auto, come descritto in Notifica utenti dei messaggi. Sebbene alcune notifiche potrebbero non avere lo stato "Risposta in attesa", l'intent ha tutti un intent in attesa Contrassegna come letto.

Per semplificare le interazioni con le notifiche, utilizza NotificationPayloadHandler, che fornisce metodi per estrarre i messaggi dalla notifica e scrivere rispondere ai messaggi nell'intento in attesa appropriato della notifica. Dopo il l'assistente vocale legge il messaggio, l'assistente vocale deve attivare il contrassegno come intent di lettura.

Soddisfa le condizioni preliminari per la funzionalità Tocca per leggere

Solo VoiceInteractionSession della voce predefinita riceve una notifica quando un utente attiva l'azione vocale per leggere e rispondere ai messaggi. Come già detto, questo assistente vocale predefinito deve dispongono dell'autorizzazione di listener di notifiche.

Diagrammi di sequenza

Queste figure mostrano i flussi logici di CarVoiceInteractionSession actions:

VOICE_ACTION_READ_NOTIFICATION

Figura 2. Diagramma di sequenza per VOICE_ACTION_READ_NOTIFICATION.

Nel caso della Figura 3, si consiglia l'app dei limiti di frequenza per le richieste di autorizzazione:

NOTIFICA_REPLY_ACTION_VOICE

Figura 3. Diagramma di sequenza per VOICE_ACTION_REPLY_NOTIFICATION.

EXCEPTION_HANDLE_ACTION_VOICE_ACTION

Figura 4. Diagramma di sequenza per VOICE_ACTION_HANDLE_EXCEPTION.

Lettura del nome dell'app

Se vuoi che l'assistente vocale legga ad alta voce il nome dell'app di messaggistica durante la lettura di un messaggio (ad esempio, "Sam di Hangouts ha detto..."), crea una funzione come quella mostrata nell'esempio di codice che segue per assicurarti che l'assistente legga il nome corretto:

@Nullable
String getMessageApplicationName(Context context, StatusBarNotification statusBarNotification) {
    ApplicationInfo info = getApplicationInfo(context, statusBarNotification.getPackageName());
    if (info == null) return null;

    Notification notification = statusBarNotification.getNotification();

    // Sometimes system packages will post on behalf of other apps, so check this
    // field for a system app notification.
    if (isSystemApp(info)
            && notification.extras.containsKey(Notification.EXTRA_SUBSTITUTE_APP_NAME)) {
        return notification.extras.getString(Notification.EXTRA_SUBSTITUTE_APP_NAME);
    } else {
        PackageManager pm = context.getPackageManager();
        return String.valueOf(pm.getApplicationLabel(info));
    }
}

@Nullable
ApplicationInfo getApplicationInfo(Context context, String packageName) {
    final PackageManager pm = context.getPackageManager();
    ApplicationInfo info;
    try {
        info = pm.getApplicationInfo(packageName, 0);
    } catch (PackageManager.NameNotFoundException e) {
        return null;
    }
    return info;
}

boolean isSystemApp(ApplicationInfo info) {
    return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}