Contenido del curso

Acceso a sensores y cámara

Servicio de speech-to-text en Flutter

Resumen

Crear un servicio de speech-to-text en Flutter implica conectar la librería de reconocimiento de voz, manejar estados de escucha y exponer la información hacia la interfaz. Aquí aprendes a estructurar ese servicio con métodos asíncronos, getters y un toggle visual para activar el micrófono, ideal si desarrollas apps con interacción por voz.

¿Cómo iniciar la escucha de voz en Flutter?

La primera funcionalidad que necesitas es un método asíncrono que arranque el listening. Este método espera la respuesta de la librería antes de cambiar el estado de la app.

Dentro del servicio creas un Future llamado startListening que recibe un booleano para validar si el reconocimiento está habilitado. Si la librería se inicializa correctamente, el estado isListening pasa a true y se ejecuta el método speech.listen, que entrega un result enlazado a la función onSpeechResult [3:20].

¿Por qué startListening debe ser asíncrono? Porque depende de la respuesta de la librería de reconocimiento de voz, que tarda milisegundos en inicializar el micrófono y devolver el estado.

En el else de la condición, una variable de texto guarda el mensaje No se pudo iniciar el reconocimiento de voz, útil para depurar y avisar al usuario qué está pasando.

¿Cómo capturar el resultado del reconocimiento de voz?

La función onSpeechResult es la que conecta lo que dice el usuario con la pantalla. Dentro de ella se accede a la propiedad recognizedWords del objeto result que entrega la librería [4:55].

Ese valor se guarda en una variable privada de tipo String, que más adelante se expone públicamente con un getter. Así, la UI puede mostrar en tiempo real lo que el dispositivo está escuchando.

  • El método recibe el result como parámetro.
  • Asigna result.recognizedWords al texto interno del servicio.
  • Permite que la pantalla refleje cada palabra reconocida.

Esta separación entre lógica y vista es clave para mantener un servicio reutilizable.

¿Cómo detener la escucha y exponer los datos?

Necesitas un método de cierre y getters públicos para que el resto de la app consuma la información sin tocar las variables privadas.

El método stopListening

Llama a speech.stop() y cambia la variable isListening a false. Con esto, el servicio deja de procesar audio y libera el micrófono [6:10].

Los getters públicos

Dos getters exponen la data hacia afuera del servicio:

  • recognizedText: devuelve el String con las palabras reconocidas.
  • isListening: devuelve un bool que indica si el micrófono está activo.

Esta es la forma idiomática en Dart de proteger el estado interno mientras permites lectura desde otras widgets.

¿Qué diferencia hay entre una propiedad privada y un getter público? La propiedad privada (con guion bajo) solo se modifica dentro del servicio. El getter público permite leer su valor desde fuera sin riesgo de alterarlo.

¿Cómo conectar el servicio con la UI de la aplicación?

El servicio se inicializa en el main junto con los demás servicios de la app. Allí creas una instancia llamada speechService y la pasas como parámetro al constructor de MyApp [7:45].

Desde MyApp la propagas hacia ModelScreen usando this.speechService, declarándola como required en el constructor de la widget. Este patrón asegura que la pantalla siempre reciba el servicio listo para usarse.

Los pasos concretos son:

  1. Instanciar speechService en el main.
  2. Pasarla al constructor de MyApp.
  3. Declararla como variable en el stateless widget.
  4. Reenviarla a ModelScreen con la palabra clave required.

De esta forma, el servicio queda disponible en toda la jerarquía de widgets sin necesidad de inyección global.

¿Cómo crear un toggle para activar el micrófono?

En la parte inferior de la UI agregas un botón y un texto. El botón ejecuta una función toggle que revisa el estado actual de isListening dentro del speechService.

La lógica es directa: si el servicio ya está escuchando, llama a stopListening. Si no, ejecuta startListening. Esto se logra accediendo a widget.speechService.isListening y aplicando un condicional ternario o un if/else [9:30].

El texto debajo del botón muestra el recognizedText, así el usuario ve en pantalla cada palabra que el dispositivo identifica. La próxima clase cubre el detalle visual y la emulación en un dispositivo físico.

¿Ya implementaste un servicio de voz en Flutter antes? Cuéntame en los comentarios qué librería usaste y qué retos enfrentaste al manejar los estados de escucha.