Pour implémenter une application d'interaction vocale, procédez comme suit:
- Créer un squelette VIA
- (Facultatif) Mettez en place une procédure de configuration/connexion.
- (Facultatif) Implémentez un écran "Settings" (Paramètres).
- Déclarez les autorisations requises dans le fichier manifeste.
- Implémenter une UI d'élément vocal
- Implémenter la reconnaissance vocale (doit inclure l'implémentation de l'API RecognitionService)
- Implémentez l'énoncé (vous pouvez éventuellement implémenter l'API TextToSpeech).
- Implémentez le traitement des commandes. Voir ce contenu en Exécution des commandes.
Les sections suivantes décrivent comment réaliser chaque étape mentionnée ci-dessus.
Créer un squelette VIA
Fichiers manifestes
Une application est détectée comme étant associée à une interaction vocale dans les cas suivants : inclus dans le fichier manifeste:
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>
Dans cet exemple :
- Les intents intégrés doivent exposer un service qui étend
VoiceInteractionService
, avec Un filtre d'intent pour l'actionVoiceInteractionService.SERVICE_INTERFACE ("android.service.voice.VoiceInteractionService")
- Ce service doit détenir l'autorisation de signature système
BIND_VOICE_INTERACTION
. - Ce service doit inclure un fichier de métadonnées
android.voice_interaction
contenant les éléments suivants: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" />
Pour en savoir plus sur chaque champ, consultez R.styleable#VoiceInteractionService
.
Étant donné que toutes les VIA sont également des services de reconnaissance vocale, vous devez également
incluez les éléments suivants dans votre fichier manifeste:
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>
Les services de reconnaissance vocale nécessitent également les métadonnées suivantes:
res/xml/recognition_service.xml
<recognition-service xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="com.example.MyRecognizerSettingsActivity" />
VoiceInteractionService, VoiceInteractionSessionService et VoiceInteractionSession
Le schéma suivant illustre le cycle de vie de chacune de ces entités:
Figure 1 : Cycles de vie
Comme indiqué précédemment, VoiceInteractionService
est le point d'entrée
à une VIA. Les principales responsabilités de ce service sont les suivantes:
- Initialisez tous les processus qui doivent rester en cours d'exécution aussi longtemps que cette VIA est active. Par exemple, la détection de mots clés.
- Signale les commandes vocales compatibles (voir Appuyer pour lire avec l'assistant vocal).
- Lancer des sessions d'interaction vocale à partir de l'écran de verrouillage (verrouillage du clavier)
Dans sa forme la plus simple, une implémentation de VoiceInteractionService serait comme ceci:
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'implémentation de VoiceInteractionService#onGetSupportedVoiceActions()
est
nécessaires pour gérer
Fonctionnalité Tap-to-Read de l'assistant vocal :
Le système utilise un VoiceInteractionSessionService pour créer et
interagir avec une VoiceInteractionSession ; Il n’a qu’une seule responsabilité,
pour démarrer de nouvelles sessions si vous y êtes invité.
public class MyVoiceInteractionSessionService extends VoiceInteractionSessionService { @Override public VoiceInteractionSession onNewSession(Bundle args) { return new MyVoiceInteractionSession(this); } }
Enfin, dans une session VoiceInteractionSession, la plupart des tâches
est fait. Une même instance de session peut être réutilisée pour effectuer plusieurs
les interactions
des utilisateurs. Dans AAOS, il existe un CarVoiceInteractionSession
d'assistance.
en aidant à implémenter certaines fonctionnalités uniques d'Automotive.
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
dispose d'un grand nombre de méthodes de rappel
expliqué dans les sections suivantes. consultez la documentation complète pour VoiceInteractionSession
.
Implémenter une procédure de configuration/connexion
La configuration et la connexion peuvent avoir lieu dans les cas suivants:
- Pendant l'intégration de l'appareil (assistant de configuration).
- Lors du changement de service d'interaction vocale (paramètres).
- Lors du premier lancement, lorsque l'application est sélectionnée.
Pour en savoir plus sur l'expérience utilisateur et les conseils visuels recommandés, consultez Assistants préchargés: conseils sur l'expérience utilisateur.
Configurer lors du changement de service vocal
L'utilisateur peut toujours sélectionner une VIA qui n'a pas été correctement configuré. Cela peut se produire pour les raisons suivantes:
- L'utilisateur a totalement ignoré l'assistant de configuration ou a ignoré la commande vocale. de configuration des interactions.
- L'utilisateur a sélectionné une VIA différente de celle configurée sur l'appareil lors de l'intégration.
Dans tous les cas, une VoiceInteractionService
a plusieurs façons d'encourager l'utilisateur
pour terminer la configuration:
- Rappel de notification.
- Réponse vocale automatique lorsque l'utilisateur essaie de s'en servir
Remarque: Il est vivement déconseillé de présenter une procédure de configuration via l'IA. sans demande explicite de l'utilisateur. Cela signifie que les CVA doivent éviter automatiquement afficher du contenu sur le HU pendant le démarrage de l'appareil ou à la suite d'un changement d'utilisateur ou déverrouiller.
Rappel de notification
Un rappel de notification est un moyen non intrusif d'indiquer qu'une configuration est nécessaire, et fournir aux utilisateurs une affordance de naviguer dans la configuration de l'assistant le flux de travail.
Figure 2. Rappel de notification
Voici comment fonctionne cette procédure:
Figure 3. Flux des rappels de notification
Réponse vocale
Il s'agit du flux le plus simple à implémenter, qui lance un énoncé sur
Un rappel VoiceInteractionSession#onShow()
, expliquant à l'utilisateur
doit être faite, puis leur demander (si la configuration est autorisée compte tenu de l'état de restriction de l'expérience utilisateur)
pour lancer le processus de configuration. Si la configuration n'est pas possible pour le moment, expliquez-le
situation.
Configuration à la première utilisation
Il est toujours possible que l'utilisateur déclenche une VIA qui n'a pas été correctement configuré. Dans ce cas:
- Informer l'utilisateur oralement de cette situation (par exemple, « Pour fonctionner correctement, Veuillez suivre quelques étapes supplémentaires... ").
- Si le moteur de restrictions de l'expérience utilisateur le permet (voir UX_RESTRICTIONS_NO_CONFIGURATION), demandez à l'utilisateur s'il souhaite démarrer la processus de configuration, puis ouvrez l'écran des paramètres de l'IVA.
- Sinon (si l'utilisateur est en train de conduire, par exemple), laissez-lui une notification cliquez sur l'option lorsque cela ne présente aucun risque.
Créer des écrans de configuration de l'interaction vocale
Les écrans de configuration et de connexion doivent être développés comme des activités régulières. Consultez le Consignes visuelles et relatives à l'expérience utilisateur pour le développement de l'interface utilisateur Assistants préchargés: conseils sur l'expérience utilisateur.
Consignes générales:
- Les VIA doivent permettre aux utilisateurs d'interrompre et de reprendre la configuration à tout moment.
- La configuration ne doit pas être autorisée si la restriction
UX_RESTRICTIONS_NO_SETUP
est en vigueur. Pour en savoir plus, consultez Consignes concernant la distraction du conducteur - Les écrans de configuration doivent correspondre au système de conception de chaque véhicule. Écran "General" (Général) la mise en page, les icônes, les couleurs et les autres aspects doivent être cohérents avec le reste de l'interface utilisateur. Voir Personnalisation pour en savoir plus.
Implémenter un écran de paramètres
Figure 4. Intégration des paramètres
Les écrans de paramètres sont des activités Android courantes. S'il est implémenté, son point d'entrée
doit être déclarée dans le res/xml/interaction_service.xml
dans le cadre de l'outil VIA.
manifestes (voir
fichiers manifestes).
La section "Paramètres" est idéale pour poursuivre la configuration et se connecter (si l'utilisateur n'a pas terminé
Vous pouvez également proposer une option de déconnexion ou de changement d'utilisateur si nécessaire. Similaire à l'option "Configuration"
écrans décrits ci-dessus, ceux-ci doivent:
- Offrir la possibilité de revenir à l'écran précédent dans la pile d'écrans (par exemple, aux Paramètres du véhicule).
- Non autorisé au volant. Pour en savoir plus, consultez les consignes relatives à la distraction du conducteur.
- Correspondre à chaque système de conception du véhicule. Pour en savoir plus, consultez Personnalisation.
Déclarer les autorisations requises dans le fichier manifeste
Les autorisations requises par une VIA peuvent être réparties en trois catégories:
- Autorisations de signature système. Il s'agit d'autorisations n'est accordé qu'aux APK préinstallés signés par le système. Les utilisateurs ne peuvent pas accorder ces autorisations, seuls les OEM peuvent les accorder lors de la création de leurs images système. Pour en savoir plus sur l'obtention d'autorisations de signature, consultez Accorder des autorisations privilégiées du système.
- Autorisations dangereuses. Il s’agit d’autorisations qu’un utilisateur doit via la boîte de dialogue PermissionsController. Les OEM peuvent pré-accorder certains de ces les autorisations au service VoiceInteractionService par défaut. Mais étant donné que cette valeur par défaut peuvent changer d'un appareil à l'autre, les applis doivent pouvoir les demander les autorisations nécessaires.
- Autres autorisations. Ce sont toutes les autres autorisations que sans intervention de l'utilisateur. Ces autorisations sont automatiquement accordées par le système.
Compte tenu de ce qui précède, la section suivante porte uniquement sur les demandes des autorisations dangereuses. Les autorisations ne doivent être demandées que lorsque l'utilisateur sur les écrans de connexion ou de configuration.
Si l'application ne dispose pas des autorisations nécessaires pour fonctionner, la procédure recommandée consiste à utiliser un énoncé vocal pour expliquer la situation au utilisateur et une notification pour fournir une affordance que l'utilisateur peut utiliser pour revenez aux écrans des paramètres de VIA. Pour plus d'informations, reportez-vous à la section 1. Rappel de notification.
Demander des autorisations sur l'écran des paramètres
Les autorisations dangereuses sont demandées à l'aide de la méthode ActivityCompat#requestPermission()
standard (ou équivalente). Pour savoir comment demander des autorisations, consultez
Demandez des autorisations d'application.
Figure 5. Demander des autorisations
Autorisation de l'écouteur des notifications
Pour implémenter le flux TTR, les ViA doivent être désignées écouteur de notifications. Il ne s'agit pas d'une autorisation en soi, mais d'une qui permet au système d'envoyer des notifications aux pour les auditeurs. Pour savoir si l'interface utilisateur a été autorisée à accéder à ces informations, applications peuvent:
- (Facultatif) Vérifiez s'il existe des écouteurs de notifications à l'avance en utilisant
CarAssistUtils#assistantIsNotificationListener()
Cela peut être fait, par exemple, pendant le flux de configuration. - (Obligatoire) Réagir à la gestion de
CarVoiceInteractionSession#onShow()
avec l'actionVOICE_ACTION_HANDLE_EXCEPTION
et l'exceptionEXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING
.
Si cet accès n'est pas pré-accordé, l'IVA doit diriger l'utilisateur vers Section "Accès aux notifications" des paramètres du véhicule, en utilisant une combinaison d'énoncés et les notifications. Le code suivant permet d'ouvrir la section appropriée du Paramètres:
private void requestNotificationListenerAccess() { Intent intent = new Intent(Settings .ACTION_NOTIFICATION_LISTENER_SETTINGS); intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName()); startActivity(intent); }
Implémenter une UI d'élément vocal
Lorsqu'un VoiceInteractionSession
reçoit un rappel onShow()
,
il peut présenter une UI d'élément vocal. Pour obtenir des consignes visuelles et relatives à l'expérience utilisateur sur l'implémentation des plaques vocales,consultez
Assistants préchargés: conseils sur l'expérience utilisateur.
Figure 6. Afficher l'élément vocal
Deux options s'offrent à vous pour implémenter cette interface utilisateur:
- Ignorer
VoiceInteractionSession#onCreateContentView()
- Lancer une activité à l'aide de
VoiceInteractionSession#startAssistantActivity()
Utiliser onCreateContentView()
Il s'agit de la méthode par défaut pour présenter une plaque vocale. VoiceInteractionSession
crée une fenêtre et gère son cycle de vie tant qu'une commande vocale
est active. Les applications doivent remplacer VoiceInteractionSession#onCreateContentView()
et retourner une vue associée à cette fenêtre dès que la session
créé. Au départ, cette vue doit être invisible. Lorsqu'une interaction
vocale commence,
cette vue devrait être visible sur VoiceInteractionSession#onShow()
puis de nouveau invisible sur 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); } … }
Lorsque vous utilisez cette méthode, vous pouvez ajuster VoiceInteractionSession#onComputeInsets()
pour tenir compte des zones
obscurcies de votre interface utilisateur.
Utiliser startAssistantActivity()
Dans ce cas, VoiceInteractionSession
délègue le traitement de la voix.
à une activité régulière. Lorsque cette option est utilisée, un VoiceInteractionSession
doit désactiver la création de sa fenêtre de contenu par défaut (voir Utiliser onCreateContentView()) sur le onPrepareShow()
.
. À VoiceInteractionSession#onShow()
, la session démarre la voix
activité de plaque à l'aide de VoiceInteractionSession#startAssistantActivity()
. Ce
lance l'interface utilisateur avec les paramètres de fenêtre et les indicateurs d'activité appropriés.
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); } … }
Pour maintenir une communication entre cette activité et la
VoiceInteractionSession
, un ensemble d'intents internes ou de liaison de service peut être
obligatoire. Par exemple, lorsque VoiceInteractionSession#onHide()
est appelé, la
doit pouvoir transmettre cette requête à l'activité.
Important : Dans l'automobile, les annotations
activités ou activités répertoriées dans la « liste d’autorisation » de l’UXR peuvent s'afficher
au volant. Cela s'applique aux activités commencées par
VoiceInteractionSession#startAssistantActivity()
également. N'oubliez pas
annoter votre activité avec <meta-data
android:name="distractionOptimized" android:value="true"/>
ou inclure ceci
l'activité dans la clé systemActivityWhitelist
du /packages/services/Car/service/res/values/config.xml
. Pour en savoir plus, consultez la section Pilote
Consignes relatives à la distraction.
Implémenter la reconnaissance vocale
Dans cette section, vous allez apprendre à implémenter la reconnaissance vocale et la reconnaissance de mots clés. Un mot clé est un mot déclencheur utilisé pour lancer une nouvelle requête. ou par commande vocale. Par exemple, "Ok Google". ou "Hey Google".
Détection de mot clé DSP
Android donne accès à un détecteur de mots clés toujours activé au niveau de la DSP en
moyenne de AlwaysOnHotwordDetector
.
pour implémenter la détection de mots clés avec une faible capacité de processeur. L'utilisation de cette fonctionnalité
se divise en deux parties:
- Instanciation d'un
AlwaysOnHotwordDetector
. - Enregistrement d'un modèle sonore pour la détection de mots clés.
VoiceInteractionService permet de créer un détecteur de mots clés à l'aide de
VoiceInteractionService#createAlwaysOnHotwordDetector()
,
en transmettant une phrase-clé et les paramètres
régionaux qu'il souhaite utiliser pour la détection. Par conséquent,
l'application reçoit un onAvailabilityChanged()
.
avec l'une des valeurs possibles suivantes:
STATE_HARDWARE_UNAVAILABLE
La fonctionnalité DSP n'est pas disponible sur le appareil. Dans ce cas, la détection de mot clé logiciel est utilisée.STATE_HARDWARE_UNSUPPORTED
Les DSP ne sont généralement pas prises en charge, mais La DSP n'accepte pas la combinaison phrase-clé et paramètres régionaux donnée. L'application peut choisir d'utiliser Détection logicielle des mots clés.STATE_HARDWARE_ENROLLED
La détection de mots clés est prête et peut être lancée en appelant la méthodestartRecognition()
.STATE_HARDWARE_UNENROLLED
Un modèle sonore pour la phrase clé demandée n'est pas mais l'inscription est possible.
L'enregistrement des modèles sonores pour la détection des mots clés peut être effectué à l'aide de IVoiceInteractionManagerService#updateKeyphraseSoundModel()
.
Vous pouvez enregistrer plusieurs modèles à la fois dans le système, mais un seul
est associé à un AlwaysOnHotwordDetector
.
La détection de mot clé DSP peut ne pas être disponible sur tous les appareils. Développeurs VIA
doit vérifier les capacités matérielles à l'aide de getDspModuleProperties()
. Pour l'exemple de code montrant
comment enregistrer des modèles de son, consultez VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java
.
Consultez la section Capture simultanée pour en savoir plus
la reconnaissance simultanée de mots clés.
Détection de mot clé logiciel
Comme indiqué ci-dessus, il est possible que la détection de mot clé DSP ne soit pas disponible (par exemple, Android Emulator ne fournit pas d'émulation DSP). Dans ce cas, la reconnaissance vocale logicielle est la seule alternative. Pour éviter d'interférer avec d'autres applications pouvant avoir besoin d'accéder au micro, les assistants virtuels doivent accéder à l'entrée audio avec:
- La capture audio doit utiliser MediaRecorder.AudioSource.HOTWORD.
- Détenir l'autorisation
android.Manifest.permission.CAPTURE_AUDIO_HOTWORD
.
Ces deux constantes ont la valeur @hide
et ne sont disponibles que pour les applications groupées.
Gérer la saisie audio et la reconnaissance vocale
L'entrée audio est implémentée à l'aide de la classe MediaRecorder.
Pour plus d'informations sur l'utilisation de cette API, consultez la page MediaRecorder.
Présentation. Les services d'interaction vocale devraient également être RecognitionService
les implémentations de classe. Toute application du système nécessitant la reconnaissance vocale utilise l'API
pour accéder à cette fonctionnalité. Pour utiliser la reconnaissance vocale et accéder au micro,
doit contenir android.permission.RECORD_AUDIO
.
Applications accédant à un RecognitionService
implémentation doivent également détenir cette autorisation.
Avant Android 10, l'accès au micro n'était accordé qu'à une seule application à la fois (à l'exception de la détection de mot clé, voir ci-dessus). À partir d'Android 10, l'accès au micro peut être partagé. Pour en savoir plus, consultez la page Partage Entrée audio.
Accéder à la sortie audio
Lorsque l'IVA est prête à fournir des réponses orales, il est important de suivez ces consignes:
- Lorsque vous demandez la priorité audio ou gérez la sortie audio, l'application
doit utiliser
AudioAttributes#USAGE_ASSISTANT
etAudioAttributes#CONTENT_TYPE_SPEECH
comme attributs audio. - Lors de la reconnaissance vocale, la sélection audio doit être demandée avec
AudioManage#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE
. Sachez que certaines applications multimédias peuvent ne pas réagir correctement aux commandes multimédias (voir la section Traitement des commandes multimédias). le curseur est supprimé.