Voice triggers. Primeros pasos con Google Glass (III)

En el anterior artículo sobre los primeros pasos con Google Glass empezamos a ver el concepto de Voice trigger, los comandos de voz que permiten lanzar nuestras aplicaciones. Vamos a hablar un poco más cerca de ellas y qué cosas podemos hacer a día de hoy con la API.

Voice triggers con prompt

Una de las primeras cosas que podemos hacer con un Voice trigger es hacerle una pregunta al usuario. Es decir, el usuario dice Ok glass, google, entonces el sistema antes de abrir la aplicación de Google, abre una interfaz en la que muestra una pregunta y espera a que el usuario responda a ella. Luego una vez el usuario responde a la pregunta, lanza la aplicación proporcionando como parámetro el texto capturado.

Prompt de la aplicación de Google Prompt de la aplicación de Google

Para asociar un prompt a nuestro voice trigger es tan sencillo como añadir una etiqueta input con un atributo prompt dentro de la etiqueta trigger de la siguiente forma:

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

Así de sencillo, con esto cuando el usuario lance nuestra aplicación, el sistema mostrará esa interfaz y capturará lo dicho por el usuario. Pero, ¿cómo recibimos esa información en nuestra aplicación? Pues como no podía ser de otra forma, a través del Intent. Para obtenerlo, debemos usar la constante RecognizerIntent.EXTRA_RESULTS, con la que obtendremos una lista de String con cada una de las palabras capturadas.

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

Creando un Voice trigger con prompt

Vamos a poner en práctica lo anterior, creamos una nueva actividad en nuestro proyecto (o creamos un proyecto nuevo como ya vimos) con su layout, donde vamos a mostrar el texto que hemos capturado del usuario.

Creamos un layout con nombre activity_askmesomething.xml, cuyo contenido será el siguiente.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="18sp"
        android:text="I ask you something and you respond"/>

    <TextView
        android:id="@+id/captured_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"/>

</LinearLayout>

Ahora creamos la actividad, enlazando con este layout.

public class AskMeSomethingActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_askmesomething);
    }
}

Ahora vamos a obtener una referencia al TextView donde vamos a mostrar el texto capturado, recomponemos el texto capturado con un StringBuilder y lo asignamos al TextView. Quedaría algo así:

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

        StringBuilder inputBuilder = new StringBuilder();
        for(String voiceToken : voiceResults) {
            inputBuilder.append(voiceToken);
            inputBuilder.append(" ");
        }

        TextView capturedInputText = (TextView)findViewById(R.id.captured_input);
        capturedInputText.setText(inputBuilder.toString());
...

Ya por último nos queda crear el Voice trigger y añadir la nueva actividad al AndroidManifest.xml. Lo primero el Voice trigger, añadimos un nuevo fichero xml que llamamos _askmesomething_trigger.xml_ con el siguiente contenido, nada que ya no hayamos visto antes.

<trigger keyword="@string/trigger_ask_me_something">
    <input prompt="@string/prompt_ask_me_something" />
</trigger>

Modificamos el fichero strings.xml para agregar las nuevas cadenas.

<string name="trigger_ask_me_something">ask me something</string>
<string name="prompt_ask_me_something">What\'s your favourite color?</string>

Y por último agregamos la actividad al AndroidManifest.xml.

...
        <activity
            android:name=".AskMeSomethingActivity"
            android:label="@string/app_name" >
            <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/askmesomething_trigger" />
        </activity>
...

Y ya tenemos todo listo, ahora solo nos falta lanzar la aplicación, decir Ok glass, ask me something y veremos la siguiente pantalla:

Prompt de nuestra aplicación Prompt de nuestra aplicación

Al responder a la pregunta, se lanzará nuestra aplicación, mostrando por pantalla lo capturado:

Pantalla con el resultado de la captura Pantalla con el resultado de la captura

Restricciones

Una última cosa que nos queda por comentar de los Voice triggers es la posibilidad de deshabilitarlos en función del estado del sistema, es decir, si alguna de las características del dispositivo no está disponible por la razón que fuera, el sistema deshabilita aquellos comandos de voz que lo requieran. Actualmente existen tres:

  • camera
  • network
  • microphone

Por ejemplo, si nuestra aplicación requiere de conexión a internet, podemos limitar su uso con el siguiente código, donde podemos ver que se ha añadido la etiqueta constraints con el atributo network a true.

<trigger keyword="@string/trigger_ask_me_something">
    <constraints network="true" />
</trigger>

Y esto es todo, el código de este artículo lo tenéis en el repositorio de esta serie de artículos, bajo la carpeta 2.VoiceTriggers.

Latest commit to the master branch on

Download as zip

Continuará…

En el próximo artículo vamos a empezar a trabajar con la Card API para crear una interfaz con la que podamos navegar e interactuar. Veremos cómo utilizar las clases Card, CardScrollView y CardScrollAdapter para conseguir una interfaz similar a la que podemos ver en las aplicaciones Google Glass, sin ir más lejos, el propio Timeline usa esta dinámica.