Entrada de voz

La entrada de voz te permite crear una interfaz realmente manos libres. Vidrio te ofrece tres formas de utilizar la entrada de voz.

Los comandos por voz principales inician Glassware desde la tarjeta Home, voz contextual comandos pueden ejecutar acciones dentro de una actividad, y la voz del sistema La actividad de reconocimiento te permite recibir entradas de voz de formato libre de los usuarios.

Comandos por voz principales

Estos comandos por voz inician Glassware desde la tarjeta principal (tarjeta Reloj). Cuando declarar un comando por voz principal, Glass crea automáticamente un elemento de menú táctil como resguardo si los usuarios deciden iniciar su Glassware con un toque Tarjeta de inicio.

Para agregar un comando por voz al menú principal de ok Glass, haz lo siguiente:

  1. Crea un recurso XML para el comando por voz en res/xml/<my_voice_trigger>.xml que usa uno de los comandos por voz existentes definidos en VoiceTriggers.Command Por ejemplo, aquí se muestra cómo usar "Iniciar una carrera".

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

    Para crear un comando por voz que le pida al usuario que diga una palabra adicional frase antes de iniciar tu actividad o servicio, incluye una input . Por ejemplo, es posible que desees hacer esto si estás con la opción "Publicar una actualización".

    <?xml version="1.0" encoding="utf-8"?>
    <trigger command="POST_AN_UPDATE">
        <input prompt="@string/glass_voice_prompt" />
    </trigger>
    
  2. Registra un filtro de intents con el com.google.android.glass.action.VOICE_TRIGGER acción en tu Manifiesto de Android. El filtro de intents inicia tu actividad o servicio si detecta usuarios que dicen tu comando por voz.

    <?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. Declara un atributo android:icon para tu actividad o servicio. Esto permite que Glass muestre un ícono para tu Glassware. ok, Glass.

    <activity |service
        android:icon="@drawable/my_icon" ...>
      ...
    </activity | service>
    
  4. Si tu comando por voz usa un mensaje de voz e inicia una actividad, obtén cualquier texto transcrito con el siguiente código (como en onResume()):

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

    Si el comando por voz inicia un servicio, el intent adicional está disponible en Devolución de llamada de onStartCommand():

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

Configura restricciones

Si necesitas una o todas las características siguientes para iniciar tu Glassware, especifícalos en el recurso res/xml/<my_voice_trigger>.xml. Si las funciones no están disponibles, Glass inhabilita el comando por voz:

  • camera
  • network
  • microphone

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

Comandos por voz contextuales

Los comandos por voz contextuales permiten a los usuarios realizar acciones a partir de las actividades. Puedes compilar comandos de voz contextuales con las APIs estándar de Android Menu, pero los usuarios pueden invocar los elementos del menú con comandos por voz en lugar de táctiles.

Para habilitar los comandos por voz contextuales para una actividad en particular:

  1. Llame al getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS) en la actividad deseada para habilitar los comandos por voz contextuales. Con esta función habilitado, el menú "ok Glass" aparece en el área del pie de página de la pantalla. cada vez que esta actividad recibe el foco.

  2. Anular onCreatePanelMenu() y manejar el caso en el que WindowUtils.FEATURE_VOICE_COMMANDS esté habilitado. Si está habilitada, aquí es donde configuras el menú por única vez, como aumentar un recurso de menú o llamando a Menu.add() métodos para crear tu sistema de menú de voz.

  3. Anular onMenuItemSelected() para manejar los comandos por voz cuando los usuarios los pronuncian. Cuando los usuarios terminan cuando seleccionas un elemento del menú, el comando por voz "ok, Glass" vuelve a aparecer en la sección del pie de página de la pantalla, listo para aceptar una voz nueva comando, siempre que la actividad permanezca en foco.

    El siguiente código habilita comandos por voz contextuales, aumenta un recurso de menú cuando corresponde, y maneja los comandos por voz cuando se pronuncian:

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

    Este es un ejemplo del recurso de menú usado en la actividad anterior. Observa que puedes crear elementos de menú anidados para una voz jerárquica menú del sistema. En el siguiente ejemplo, el primer elemento del menú puede Se puede acceder de la siguiente manera: ok vidrio, Muéstrame perros, 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. (Opcional) Anulación onPreparePanel(): comprobar si WindowUtils.FEATURE_VOICE_COMMANDS está habilitado. Si se habilita, puedes hacer otra lógica para configurar el sistema del menú como agregar o quitar ciertos elementos del menú en función de ciertos criterios. Puedes activar o desactivar los menús de voz contextuales (mostrar true) y desactivarlos (devuelve false) según algunos criterios. Por ejemplo:

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

Compatibilidad simultánea de menús táctiles y de voz

Debido a que los comandos de voz contextuales usan las APIs de Android Menu existentes, puedes reutilizar gran parte del código y los recursos que ya tienes para los menús táctiles y, al mismo tiempo, admitir ambos tipos de menús.

Solo debes verificar la función Window.FEATURE_OPTIONS_PANEL además de la función WindowUtils.FEATURE_VOICE_COMMANDS que ya están comprobando algunos métodos y, luego, agregan lógica para abrir la pantalla táctil en alguna acción del usuario, como un toque.

Por ejemplo, puedes cambiar la actividad anterior ejemplo para agregar compatibilidad con menús táctiles como este (los cambios tienen comentarios):

// 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) {
    ...
}

Con estos cambios, puedes presionar o decir Ok Glass para mostrar tu menú.

Uso de comandos por voz no listados para el desarrollo

Cuando desees distribuir tu contenido de cristal, debes utilizar el producto principal aprobado comandos por voz en VoiceTriggers.Command y los comandos de voz contextuales aprobados ContextualMenus.Command

Si quieres usar comandos por voz que no están disponibles en el GDK, puedes solicitar un permiso de Android en tu archivo AndroidManifest.xml:

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

Usar comandos por voz principales que no están en la lista

  1. Declara un valor de cadena en res/values/strings.xml que defina el nombre del activador por voz. De manera opcional, declara un mensaje de voz para mostrar el objeto Glassware de reconocimiento de voz antes de iniciarlo.

    <?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. Crea un recurso XML para el activador de voz en res/xml/<my_voice_trigger>.xml En el caso de los comandos por voz que no aparecen en la lista, debes usar el atributo keyword en lugar del atributo command que se usa para aprobados comandos por voz. El atributo keyword debe ser una referencia a la cadena. recurso que define el comando de voz. Para un simple activador de voz que inicie una actividad o servicio de inmediato, solo especifica el elemento trigger:

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

    Para crear un activador por voz que le indique al usuario que hable una vez frase antes de iniciar tu actividad o servicio, incluye un elemento de entrada y

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

Usar comandos por voz contextuales que no figuran en la lista

Cuando crees elementos de menú, usa cualquier texto para el título del elemento de menú. Por ejemplo:

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

Iniciando reconocimiento de voz


La herramienta Glassware de reconocimiento de voz espera a que los usuarios hablen y muestra el una transcripción del texto. Para iniciar la actividad, haz lo siguiente:

  1. Llama a startActivityForResult() con el intent ACTION_RECOGNIZE_SPEECH. Los siguientes extras de intent son compatibles cuando se inicia la actividad:
  2. Anula el onActivityResult() para recibir el texto transcrito del EXTRA_RESULTS intent adicional. Se llama a esta devolución de llamada cuando los usuarios terminan de hablar.

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