Assistente vocale Tocca per leggere

Android Automotive considera la voce un componente cruciale per interazioni sicure durante la guida e uno dei modi più sicuri con cui gli utenti possono interagire con il sistema operativo Android Automotive durante la guida. Di conseguenza, abbiamo ampliato le API degli assistenti vocali Android (inclusa VoiceInteractionSession ) per consentire agli assistenti vocali di eseguire attività per gli utenti che possono essere difficili da eseguire durante la guida.

Tap-to-Read consente agli assistenti vocali di leggere e rispondere ai messaggi di testo per conto dell'utente, quando l'utente interagisce con le notifiche dei messaggi. Per fornire questa funzionalità, puoi integrare un assistente vocale con CarVoiceInteractionSession .

In Automotive, le notifiche pubblicate nel Centro notifiche identificato come INBOX o INBOX_IN_GROUP (ad esempio, messaggi SMS) includono un pulsante Riproduci . L'utente può fare clic su Riproduci per fare in modo che l'assistente vocale selezionato legga la notifica ad alta voce e, facoltativamente, risponda a voce.

Notifica tocca per leggere

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

Integrazione 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 in auto devono integrarsi con le interazioni vocali Android esistenti. Per ulteriori informazioni, consulta Assistente Google per Android (ad eccezione di VoiceInteractionSession ). Sebbene tutti gli elementi API di interazione vocale rimangano gli stessi implementati sui dispositivi mobili, CarVoiceInteractionSession (descritto in Implementare CarVoiceInteractionSession ) sostituisce VoiceInteractionSession . Per ulteriori informazioni consultare queste pagine:

Implementare CarVoiceInteractionSession

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

La differenza fondamentale tra le classi CarVoiceInteractionSession e VoiceInteractionSession è che CarVoiceInteractionSession passa 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 ciascuna classe sono elencati nella tabella seguente:

CarVoiceInteractionSession SessioneInterazioneVoce
onShow accetta questi tre parametri:
  • args
  • showFlags
  • actions
onShow accetta questi due parametri:
  • args
  • showFlags

Cambiamenti in Android 10

A partire da Android 10, la piattaforma chiama VoiceInteractionService.onGetSupportedVoiceActions per rilevare quali azioni sono supportate. L'assistente vocale sovrascrive 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 tabella seguente. Per i dettagli su ciascuna azione, vedere Diagrammi di sequenza .

Azione Carico utile previsto Azione di interazione vocale prevista
VOICE_ACTION_READ_NOTIFICATION Leggere i messaggi ad alta voce all'utente e quindi attivare nuovamente l'intento Contrassegna come letto in sospeso quando i messaggi vengono letti correttamente. Facoltativamente, richiedere una risposta all'utente.
VOICE_ACTION_REPLY_NOTIFICATION Parcellabile con chiave.
KEY_NOTIFICATION mappato su StatusBarNotification .
Richiede android.permission.BIND_NOTIFICATION_LISTENER_SERVICE .
Richiedere all'utente di dichiarare il messaggio di risposta, inserire il messaggio di risposta nel RemoteInputReply dell'intento in sospeso e quindi attivare l'intento in sospeso.
VOICE_ACTION_HANDLE_EXCEPTION Stringa con chiave.
KEY_EXCEPTION mappato su ExceptionValue (descritto in Valori di eccezione ).
KEY_FALLBACK_ASSISTANT_ENABLED che mappa su un valore booleano. Se il valore è true , l'assistente di fallback in grado di gestire la richiesta dell'utente è stato disabilitato.
L'azione prevista da intraprendere per l'eccezione è definita nella documentazione dell'eccezione.

Valori di eccezione

EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING indica all'assistente vocale che manca l'autorizzazione Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE e di ottenere questa autorizzazione dall'utente.

Richiedi l'autorizzazione per l'ascolto delle notifiche

Se l'assistente vocale predefinito non dispone dell'autorizzazione per l'ascolto delle notifiche, il FallbackAssistant della piattaforma (se abilitato dal produttore dell'auto) potrebbe leggere il messaggio ad alta voce prima che l'assistente vocale riceva la notifica di richiedere l'autorizzazione. Per determinare se FallbackAssistant è abilitato e ha letto il messaggio, l'assistente vocale deve controllare il valore booleano KEY_FALLBACK_ASSISTANT_ENABLED nel payload.

La piattaforma consiglia all'assistente vocale di aggiungere una logica di limitazione della velocità per il numero di volte in cui viene richiesta questa autorizzazione. Ciò rispetta l'utente che non vuole concedere all'assistente vocale questa autorizzazione e preferisce che FallbackAssistant legga i messaggi di testo ad alta voce. Richiedere l'autorizzazione a un utente ogni volta che l'utente preme Riproduci in una notifica di messaggio può costituire un'esperienza utente negativa. La piattaforma non impone limiti di velocità per conto dell'assistente vocale.

Quando si richiede l'autorizzazione all'ascolto delle notifiche, l'assistente vocale deve utilizzare CarUxRestrictionsManager per determinare se un utente è parcheggiato o sta guidando. Se l'utente sta guidando, l'assistente vocale visualizza una notifica che fornisce istruzioni su come concedere l'autorizzazione. Ciò aiuta (e ricorda) all'utente di concedere l'autorizzazione quando è più sicuro.

Lavora con StatusBarNotification

StatusBarNotification passato con le azioni vocali Leggi e Rispondi si trova sempre in una notifica di messaggistica compatibile con l'auto, come descritto in Notifica messaggi agli utenti . Anche se alcune notifiche potrebbero non avere l'intento Risposta in sospeso, tutte hanno l'intento Contrassegna come letto in sospeso.

Per semplificare le interazioni con le notifiche, utilizzare NotificationPayloadHandler , che fornisce metodi per estrarre messaggi dalla notifica e scrivere i messaggi di risposta nell'intento in sospeso appropriato della notifica. Dopo che l'assistente vocale ha letto il messaggio, deve attivare l'intento Contrassegna come letto.

Soddisfare i prerequisiti Tocca per leggere

Solo VoiceInteractionSession dell'assistente vocale predefinito viene avvisato quando un utente attiva l'azione vocale per leggere e rispondere ai messaggi. Come accennato in precedenza, questo assistente vocale predefinito deve avere anche l'autorizzazione di ascolto delle notifiche.

Diagrammi di sequenza

Queste figure mostrano i flussi logici delle CarVoiceInteractionSession actions :

VOICE_ACTION_READ_NOTIFICAZIONE

Figura 2. Diagramma di sequenza per VOICE_ACTION_READ_NOTIFICATION.

Nel caso della Figura 3, si consiglia l'applicazione dei limiti di velocità sulle richieste di autorizzazione:

VOICE_ACTION_REPLY_NOTIFICATION

Figura 3. Diagramma di sequenza per VOICE_ACTION_REPLY_NOTIFICATION.

VOICE_ACTION_HANDLE_EXCEPTION

Figura 4. Diagramma di sequenza per VOICE_ACTION_HANDLE_EXCEPTION.

Leggi il nome dell'app

Se desideri che il tuo assistente vocale legga ad alta voce il nome dell'app di messaggistica durante la lettura del messaggio (ad esempio, "Sam di Hangouts ha detto..."), crea una funzione come quella mostrata nell'esempio di codice seguente per assicurarti che l'assistente stia leggendo il messaggio 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;
}