Assistant vocal Tap-to-Read

Android Automotive considère la voix comme un élément crucial pour des interactions en toute sécurité et l'un des moyens les plus sûrs pour les utilisateurs d'interagir avec le système d'exploitation Android Automotive tout en conduisant. En conséquence, nous avons étendu les API de l'assistant vocal Android (y compris VoiceInteractionSession ) pour permettre aux assistants vocaux d'effectuer des tâches pour les utilisateurs qui peuvent être difficiles à accomplir en conduisant.

Tap-to-Read permet aux assistants vocaux de lire et de répondre aux messages texte au nom de l'utilisateur, lorsque celui-ci interagit avec les notifications de messages. Pour fournir cette fonctionnalité, vous pouvez intégrer un assistant vocal avec CarVoiceInteractionSession .

Dans l'automobile, les notifications publiées dans le centre de notifications identifiées comme INBOX ou INBOX_IN_GROUP (par exemple, les messages SMS) incluent un bouton Lecture . L'utilisateur peut cliquer sur Lecture pour que l'assistant vocal sélectionné lise la notification à haute voix et éventuellement réponde vocalement.

Notification par pression pour lire

Figure 1. Notification Tap-to-Read avec le bouton Lecture.

Intégrer avec CarVoiceInteractionSession

Les sections suivantes décrivent comment intégrer un assistant vocal avec CarVoiceInteractionSession .

Prise en charge des interactions vocales

Les applications qui fournissent des services d'interaction vocale en voiture doivent s'intégrer aux interactions vocales Android existantes. Pour en savoir plus, consultez Google Assistant pour Android (à l'exception de VoiceInteractionSession ). Bien que tous les éléments de l'API d'interaction vocale restent les mêmes que ceux implémentés sur les appareils mobiles, CarVoiceInteractionSession (décrit dans Implémenter CarVoiceInteractionSession ) remplace VoiceInteractionSession . Pour plus d'informations, consultez ces pages :

Implémenter CarVoiceInteractionSession

CarVoiceInteractionSession expose des API que vous pouvez utiliser pour permettre aux assistants vocaux de lire des messages texte à haute voix, puis de répondre à ces messages au nom de l'utilisateur.

La principale différence entre les classes CarVoiceInteractionSession et VoiceInteractionSession est que CarVoiceInteractionSession transmet l'action dans onShow afin que l'assistant vocal puisse détecter le contexte de la demande de l'utilisateur dès que CarVoiceInteractionSession démarre une session. Les paramètres de onShow pour chaque classe sont répertoriés dans le tableau suivant :

VoitureVoixInteractionSession Session d'interaction vocale
onShow prend ces trois paramètres :
  • args
  • showFlags
  • actions
onShow prend ces deux paramètres :
  • args
  • showFlags

Changements dans Android 10

À partir d'Android 10, la plateforme appelle VoiceInteractionService.onGetSupportedVoiceActions pour détecter les actions prises en charge. L'assistant vocal remplace et implémente VoiceInteractionService.onGetSupportedVoiceActions , comme illustré dans l'exemple suivant :

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;
   }
}

Les actions valides sont décrites dans le tableau suivant. Pour plus de détails sur chaque action, voir Diagrammes de séquence .

Action Charge utile attendue Action d'interaction vocale attendue
VOICE_ACTION_READ_NOTIFICATION Lisez les messages à voix haute à l'utilisateur, puis déclenchez l'intention Marquer comme lecture en attente lorsque les messages sont lus avec succès. Si vous le souhaitez, demandez à l'utilisateur de répondre.
VOICE_ACTION_REPLY_NOTIFICATION Colisable avec clé.
KEY_NOTIFICATION qui correspond à StatusBarNotification .
Nécessite android.permission.BIND_NOTIFICATION_LISTENER_SERVICE .
Invitez l'utilisateur à énoncer le message de réponse, saisissez le message de réponse dans le RemoteInputReply de l'intention en attente, puis déclenchez l'intention en attente.
VOICE_ACTION_HANDLE_EXCEPTION Chaîne avec clé.
KEY_EXCEPTION qui correspond à ExceptionValue (décrit dans Valeurs d'exception ).
KEY_FALLBACK_ASSISTANT_ENABLED qui correspond à une valeur booléenne. Si la valeur est true , l'assistant de secours capable de gérer la demande de l'utilisateur a été désactivé.
L'action attendue à entreprendre pour l'exception est définie dans la documentation de l'exception.

Valeurs d'exception

EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING indique à l'assistant vocal qu'il lui manque l'autorisation Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE et qu'il doit obtenir cette autorisation de l'utilisateur.

Demander l'autorisation de l'écouteur de notification

Si l'assistant vocal par défaut ne dispose pas de l'autorisation d'écoute des notifications, le FallbackAssistant de la plateforme (s'il est activé par le constructeur automobile) peut lire le message à haute voix avant que l'assistant vocal ne soit informé de la demande d'autorisation. Pour déterminer si FallbackAssistant est activé et a lu le message, l'assistant vocal doit vérifier la valeur booléenne KEY_FALLBACK_ASSISTANT_ENABLED dans la charge utile.

La plateforme recommande à l'assistant vocal d'ajouter une logique de limitation de débit pour le nombre de fois que cette autorisation est demandée. Cela respecte l'utilisateur qui ne souhaite pas accorder cette autorisation à l'assistant vocal et préfère que FallbackAssistant lise les messages texte à haute voix. Demander l'autorisation à un utilisateur chaque fois que l'utilisateur appuie sur Lecture lors d'une notification de message peut être une expérience utilisateur négative. La plateforme n'impose pas de limites de débit de la part de l'assistant vocal.

Lors de la demande d'autorisation d'écoute de notification, l'assistant vocal doit utiliser CarUxRestrictionsManager pour déterminer si un utilisateur est garé ou conduit. Si l'utilisateur conduit, l'assistant vocal affiche une notification fournissant des instructions sur la manière d'accorder l'autorisation. Cela aide (et rappelle) à l'utilisateur d'accorder l'autorisation lorsque cela est plus sûr.

Travailler avec StatusBarNotification

StatusBarNotification transmise avec les actions vocales Lire et Répondre sont toujours dans une notification de messagerie compatible avec la voiture, comme décrit dans Notifier les utilisateurs des messages . Bien que certaines notifications puissent ne pas avoir l’intention de réponse en attente, elles ont toutes l’intention d’attente Marquer comme lu.

Pour rationaliser les interactions avec les notifications, utilisez NotificationPayloadHandler , qui fournit des méthodes pour extraire les messages de la notification et écrire les messages de réponse dans l'intention en attente appropriée de la notification. Une fois que l'assistant vocal a lu le message, il doit déclencher l'intention Marquer comme lu.

Satisfaire aux conditions préalables du Tap-to-Read

Seule VoiceInteractionSession de l'assistant vocal par défaut est avertie lorsqu'un utilisateur déclenche l'action vocale pour lire et répondre aux messages. Comme mentionné ci-dessus, cet assistant vocal par défaut doit également disposer de l'autorisation d'écoute des notifications.

Diagrammes de séquence

Ces figures affichent les flux logiques des CarVoiceInteractionSession actions :

VOICE_ACTION_READ_NOTIFICATION

Figure 2. Diagramme de séquence pour VOICE_ACTION_READ_NOTIFICATION.

Dans le cas de la figure 3, l'application de limites de débit sur les demandes d'autorisation est recommandée :

VOICE_ACTION_REPLY_NOTIFICATION

Figure 3. Diagramme de séquence pour VOICE_ACTION_REPLY_NOTIFICATION.

VOICE_ACTION_HANDLE_EXCEPTION

Figure 4. Diagramme de séquence pour VOICE_ACTION_HANDLE_EXCEPTION.

Lire le nom de l'application

Si vous souhaitez que votre assistant vocal lise à haute voix le nom de l'application de messagerie pendant la lecture du message (par exemple, "Sam de Hangouts a dit..."), créez une fonction comme celle présentée dans l'exemple de code suivant pour garantir que l'assistant lit le nom de l'application de messagerie. Nom correct:

@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;
}