Saisie vocale

La saisie vocale vous permet de créer une interface mains libres. Glass propose trois manières d'utiliser la saisie vocale.

Les commandes vocales principales démarrent Glassware à partir de la carte d'accueil, les commandes vocales contextuelles peuvent exécuter des actions dans une activité, et l'activité de reconnaissance vocale du système vous permet de recevoir des entrées vocales de forme libre de la part des utilisateurs.

Commandes vocales principales

Ces commandes vocales lancent Glassware depuis la carte d'accueil (carte Horloge). Lorsque vous déclarez une commande vocale principale, Glass crée automatiquement un élément de menu tactile en remplacement si les utilisateurs décident de démarrer votre Glassware en appuyant sur la carte d'accueil.

Pour ajouter une commande vocale au menu principal Ok Glass:

  1. Créez une ressource XML pour la commande vocale dans res/xml/<my_voice_trigger>.xml qui utilise l'une des commandes vocales existantes définies dans VoiceTriggers.Command. Par exemple, voici comment démarrer une course.

    <?xml version="1.0" encoding="utf-8"?>
    <trigger command="START_A_RUN" />
    

    Pour créer une commande vocale qui invite l'utilisateur à prononcer une expression supplémentaire avant de lancer votre activité ou votre service, incluez également un élément input. Par exemple, vous pouvez effectuer cette opération si vous utilisez l'option "Publier une mise à jour".

    <?xml version="1.0" encoding="utf-8"?>
    <trigger command="POST_AN_UPDATE">
        <input prompt="@string/glass_voice_prompt" />
    </trigger>
    
  2. Enregistrez un filtre d'intent à l'aide de l'action com.google.android.glass.action.VOICE_TRIGGER dans votre fichier manifeste Android. Le filtre d'intent démarre votre activité ou votre service s'il détecte que les utilisateurs prononcent votre commande vocale.

    <?xml version="1.0" encoding="utf-8"?>
    <application ...>
        <activity | service ...>
            <intent-filter>
                <action android:name=
                        "com.google.android.glass.action.VOICE_TRIGGER" />
            </intent-filter>
            <meta-data android:name="com.google.android.glass.VoiceTrigger"
                android:resource="@xml/my_voice_trigger" />
        </activity | service>
        // ...
    </application>
    
  3. Déclarez un attribut android:icon pour votre activité ou service. Cela permet à Glass d'afficher une icône pour votre Glassware dans le menu tactile ok, Glass.

    <activity |service
        android:icon="@drawable/my_icon" ...>
      ...
    </activity | service>
    
  4. Si votre commande vocale utilise une invite vocale et démarre une activité, obtenez tout texte transcrit avec le code suivant (par exemple, dans onResume()):

    ArrayList<String> voiceResults = getIntent().getExtras()
            .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
    

    Si la commande vocale démarre un service, l'intent supplémentaire est disponible dans le rappel onStartCommand():

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        ArrayList<String> voiceResults = intent.getExtras()
                .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
        // ...
    }
    

Définition des contraintes

Si vous avez besoin d'une ou de toutes les fonctionnalités suivantes pour démarrer votre Glassware, spécifiez-les dans la ressource res/xml/<my_voice_trigger>.xml. Si les fonctionnalités ne sont pas disponibles, Glass désactive la commande vocale:

  • camera
  • network
  • microphone

    <trigger command="POST_AN_UPDATE">
        <constraints
            camera="true"
            network="true" />
    </trigger>
    

Commandes vocales contextuelles

Les commandes vocales contextuelles permettent aux utilisateurs d'effectuer des actions à partir d'activités. Vous pouvez créer des commandes vocales contextuelles à l'aide des API de menu Android standards, mais les utilisateurs peuvent appeler les éléments de menu à l'aide de commandes vocales au lieu d'appuyer.

Pour activer les commandes vocales contextuelles pour une activité particulière:

  1. Appelez getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS) dans l'activité souhaitée pour activer les commandes vocales contextuelles. Lorsque cette fonctionnalité est activée, le menu OK Glass s'affiche dans la zone du pied de page de l'écran chaque fois que cette activité est sélectionnée.

  2. Ignorez onCreatePanelMenu() et gérez le cas où WindowUtils.FEATURE_VOICE_COMMANDS est activé. Si cette option est activée, c'est ici que vous allez configurer le menu ponctuel, en gonflant une ressource de menu ou en appelant les méthodes Menu.add() pour créer votre système de menus vocaux.

  3. Remplacez onMenuItemSelected() pour gérer les commandes vocales lorsque les utilisateurs les parlent. Lorsque les utilisateurs ont terminé de sélectionner un élément de menu, la commande vocale "OK, Glass" réapparaît automatiquement dans la section de pied de page de l'écran. Elle est prête à accepter une nouvelle commande vocale, tant que l'activité reste active.

    Le code suivant active les commandes vocales contextuelles, gonfle une ressource de menu le cas échéant et gère les commandes vocales lorsqu'elles sont énoncées:

    public class ContextualMenuActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle bundle) {
            super.onCreate(bundle);
    
            // Requests a voice menu on this activity. As for any other
            // window feature, be sure to request this before
            // setContentView() is called
            getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS);
            setContentView(R.layout.activity_main);
        }
    
        @Override
        public boolean onCreatePanelMenu(int featureId, Menu menu) {
            if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
                getMenuInflater().inflate(R.menu.main, menu);
                return true;
            }
            // Pass through to super to setup touch menu.
            return super.onCreatePanelMenu(featureId, menu);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
    
        @Override
        public boolean onMenuItemSelected(int featureId, MenuItem item) {
            if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
                switch (item.getItemId()) {
                    case R.id.dogs_menu_item:
                        // handle top-level dogs menu item
                        break;
                    case R.id.cats_menu_item:
                        // handle top-level cats menu item
                        break;
                    case R.id.lab_menu_item:
                        // handle second-level labrador menu item
                        break;
                    case R.id.golden_menu_item:
                        // handle second-level golden menu item
                        break;
                    case R.id.calico_menu_item:
                        // handle second-level calico menu item
                        break;
                    case R.id.cheshire_menu_item:
                        // handle second-level cheshire menu item
                        break;
                    default:
                        return true;
                }
                return true;
            }
            // Good practice to pass through to super if not handled
            return super.onMenuItemSelected(featureId, item);
        }
    }
    

    Voici un exemple de ressource de menu utilisée par l'activité précédente. Notez que vous pouvez créer des éléments de menu imbriqués pour un système de menus vocaux hiérarchique. Dans l'exemple suivant, le premier élément de menu est accessible comme suit : ok verre, Show me dogs, Labrador.

    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- Use the constants defined in the ContextualMenus.Command enum-->
        <item
            android:id="@+id/dogs_menu_item"
            android:title="@string/show_me_dogs">
            <menu>
                <item
                    android:id="@+id/lab_menu_item"
                    android:title="@string/labrador" />
                <item
                    android:id="@+id/golden_menu_item"
                    android:title="@string/golden" />
            </menu>
        </item>
        <item
            android:id="@+id/cats_menu_item"
            android:title="@string/show_me_cats">
            <menu>
                <item
                    android:id="@+id/cheshire_menu_item"
                    android:title="@string/cheshire" />
                <item
                    android:id="@+id/calico_menu_item"
                    android:title="@string/calico" />
            </menu>
        </item>
    </menu>
    
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- Use the constants defined in the ContextualMenus.Command enum-->
        <item
            android:id="@+id/play_menu_item"
            android:title="PLAY_MUSIC" />
        <item
            android:id="@+id/pause_menu_item"
            android:title="PAUSE_MUSIC" />
    </menu>
    
  4. (Facultatif) Remplacez onPreparePanel(), en vérifiant si WindowUtils.FEATURE_VOICE_COMMANDS est activé ou non. Si cette option est activée, vous pouvez utiliser d'autres logiques pour configurer le système de menus, telles que l'ajout et la suppression de certains éléments de menu en fonction de certains critères. Vous pouvez également activer ou désactiver les menus de voix contextuelle (retour true) (renvoyer false) en fonction de certains critères. Exemple :

        private boolean mVoiceMenuEnabled;
        ...
        @Override
        public boolean onPreparePanel(int featureId, View view, Menu menu) {
            if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
            // toggle this boolean on and off based on some criteria
                return mVoiceMenuEnabled;
            }
            // Good practice to call through to super for other cases
            return super.onPreparePanel(featureId, view, menu);
        }
    

Compatibilité avec les menus vocaux et tactiles simultanément

Étant donné que les commandes vocales contextuelles utilisent les API de menu Android existantes, vous pouvez réutiliser une grande partie du code et des ressources dont vous disposez pour les menus tactiles, et les deux types de menus sont compatibles.

Il vous suffit de rechercher la fonctionnalité Window.FEATURE_OPTIONS_PANEL en plus de la fonctionnalité WindowUtils.FEATURE_VOICE_COMMANDS que vous avez déjà recherchée dans plusieurs méthodes, puis d'ajouter une logique pour ouvrir le menu tactile en cas d'action de l'utilisateur, telle qu'une pression du doigt.

Par exemple, vous pouvez modifier l'exemple d'activité précédent pour rendre les menus tactiles compatibles comme suit (les modifications sont commentées):

// 1. Check for Window.FEATURE_OPTIONS_PANEL
// to inflate the same menu resource for touch menus.
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
    if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS ||
            featureId == Window.FEATURE_OPTIONS_PANEL) {
    ...
}

// 2. Check for Window.FEATURE_OPTIONS_PANEL
// to handle touch menu item selections.
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
    if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS ||
            featureId == Window.FEATURE_OPTIONS_PANEL) {
    ...
}

Avec ces modifications, vous pouvez appuyer ou dire OK verre pour afficher votre menu.

Utiliser les commandes vocales non répertoriées pour le développement

Lorsque vous souhaitez distribuer votre Glassware, vous devez utiliser les commandes vocales principales approuvées dans VoiceTriggers.Command et les commandes vocales contextuelles approuvées dans ContextualMenus.Command.

Si vous souhaitez utiliser des commandes vocales qui ne sont pas disponibles dans GDK, vous pouvez demander une autorisation Android dans votre fichier AndroidManifest.xml:

<uses-permission
     android:name="com.google.android.glass.permission.DEVELOPMENT" />

Utiliser les commandes vocales principales non répertoriées

  1. Déclarez une valeur de chaîne dans res/values/strings.xml qui définit le nom de votre déclencheur vocal. Si vous le souhaitez, vous pouvez déclarer une commande vocale pour afficher les lunettes Glassware de reconnaissance vocale avant de les démarrer.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="glass_voice_trigger">read me a story</string>
        <string name="glass_voice_prompt">what story?</string>
    </resources>
    
  2. Créez une ressource XML pour le déclencheur vocal dans res/xml/<my_voice_trigger>.xml. Pour les commandes vocales non répertoriées, vous devez utiliser l'attribut keyword au lieu de l'attribut command pour les commandes vocales approuvées. L'attribut keyword doit être une référence à la ressource de chaîne définissant la commande vocale. Pour un déclencheur vocal simple qui démarre immédiatement une activité ou un service, spécifiez simplement l'élément trigger:

    <?xml version="1.0" encoding="utf-8"?>
    <trigger keyword="@string/glass_voice_trigger" />
    

    Pour créer un déclencheur vocal qui invite l'utilisateur à énoncer une expression supplémentaire avant de démarrer votre activité ou votre service, incluez également un élément d'entrée:

    <?xml version="1.0" encoding="utf-8"?>
    <trigger keyword="@string/glass_voice_trigger">
        <input prompt="@string/glass_voice_prompt" />
    </trigger>
    

Utiliser des commandes vocales contextuelles non répertoriées

Lorsque vous créez des éléments de menu, utilisez n'importe quel texte comme titre. Exemple :

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Use the constants defined in the ContextualMenus.Command enum-->
    <item
        android:id="@+id/pizza_menu_item"
        android:title="@string/find_pizza" />
</menu>

Lancement de la reconnaissance vocale


La reconnaissance vocale Glassware attend que l'utilisateur parle et renvoie le texte transcrit. Pour démarrer l'activité:

  1. Appelez startActivityForResult() avec l'intent ACTION_RECOGNIZE_SPEECH. Les options d'intent supplémentaires suivantes sont acceptées lors du démarrage de l'activité :
  2. Ignorez le rappel onActivityResult() pour recevoir le texte transcrit de l'intent EXTRA_RESULTS supplémentaire. Ce rappel est appelé lorsque les utilisateurs ont fini de parler.

    private static final int SPEECH_REQUEST = 0;
    
    private void displaySpeechRecognizer() {
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        startActivityForResult(intent, SPEECH_REQUEST);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode,
            Intent data) {
        if (requestCode == SPEECH_REQUEST && resultCode == RESULT_OK) {
            List<String> results = data.getStringArrayListExtra(
                    RecognizerIntent.EXTRA_RESULTS);
            String spokenText = results.get(0);
            // Do something with spokenText.
        }
        super.onActivityResult(requestCode, resultCode, data);
    }