Contenido del curso

Acceso a sensores y cámara

Cámara en Flutter con BLoC y modal

Resumen

Integrar la cámara en una app de Flutter usando el patrón BLoC te permite capturar fotos, extraer datos como montos y abrirlos en un modal para registrar ingresos o gastos. Esta guía te muestra cómo conectar el repositorio, los estados y los permisos en iOS y Android para que tu flujo funcione de extremo a extremo.

¿Cómo conectar el widget modal con el BLoC en Flutter?

El primer paso es separar el modal en su propio widget para que sea reutilizable y pueda acceder al BLoC y a toda la información que ya manejas. En lugar de invocar el modal directamente desde la pantalla, lo llamas a través de la funcionalidad takePicture que vive dentro del bloque.

Desde el contexto haces la lectura del BLoC y disparas el método addTransactionFromImage, pasándole el path de la imagen. Así, cada vez que el usuario active esa función, se ejecuta todo el proceso: abrir cámara, tomar foto, extraer texto y abrir el modal.

¿Qué hace el método addTransactionFromImage? Recibe la ruta de una imagen, llama al repositorio para procesarla y devuelve el monto extraído al BLoC, que luego dispara el modal de ingreso o gasto.

¿Cómo crear el estado showTransactionModalState?

En la sección del notebook defines la lectura de la funcionalidad y llamas a un nuevo estado llamado showTransactionModalState. Le envías el amount capturado y cierras la línea.

Luego vas a la carpeta de estados, tomas una de las clases existentes como plantilla y replicas la estructura. Este estado queda esperando el amount y lo inicializa al recibirlo. Para pasar el dato, creas un override que contiene un objeto con la propiedad amount, donde guardas el monto total.

¿Cómo escuchar cambios de estado con BlocListener?

El BlocListener es el widget que monitorea constantemente el estado del BLoC y reacciona cuando hay cambios. Lo agregas en la sección de UI, dentro del navbar, para que esté siempre activo mientras la pantalla esté visible.

Dentro del listener defines el contexto, el estado a observar y el condicional. Si el estado está presente y contiene un monto válido, accedes al widget del modal y le pasas el dato.

  • Llamas a takePicture para abrir la cámara desde el repositorio.
  • El BLoC revisa de forma continua si ya hay un amount disponible.
  • Cuando el monto existe, se abre el modal de income o expense.

Un detalle técnico: el amount viene como double, pero el modal espera un string. Por eso haces la conversión usando state.amount.toString() antes de inyectarlo en el widget.

¿Para qué sirve un BlocListener? Es un widget que escucha cambios de estado en un BLoC y ejecuta efectos secundarios, como abrir un modal o mostrar un snackbar, sin reconstruir toda la UI.

¿Qué flujo sigue la app al tomar una foto?

El flujo completo conecta cámara, repositorio, BLoC y UI en una sola cadena de eventos. Así se ve paso a paso:

  1. El usuario activa takePicture desde el botón.
  2. El repositorio abre la cámara y captura la imagen.
  3. Se extrae el texto y se identifica el monto.
  4. El BLoC actualiza showTransactionModalState con el amount.
  5. El BlocListener detecta el cambio y abre el modal con el dato precargado.

Con esa secuencia, evitas acoplar la lógica de cámara con la UI y mantienes cada capa enfocada en una sola responsabilidad.

¿Cómo configurar permisos de cámara en iOS y Android?

Antes de emular la app necesitas declarar los permisos en ambas plataformas. Sin esto, el sistema operativo bloquea el acceso a la cámara y al almacenamiento.

Para iOS abres la carpeta ios y editas el archivo Info.plist, donde agregas la clave de permiso de cámara con su descripción de uso. Esa descripción es la que aparece en el popup que ve el usuario.

En Android vas a android/app/src/main y editas el AndroidManifest.xml. Allí declaras tres permisos:

  • Permiso para usar la cámara y tomar la foto.
  • Permiso para acceder al almacenamiento de la galería.
  • Permiso de escritura para guardar la imagen.

Además, en Android debes agregar el provider al final del bloque <application> dentro del manifest. Ese provider habilita el acceso seguro a archivos temporales generados por la cámara.

¿Por qué Android necesita un provider extra? Desde Android 7 el sistema bloquea URIs de archivos directos. El FileProvider genera URIs seguras para que la cámara pueda guardar y compartir la foto sin errores de permisos.

Con todo conectado (BLoC, listener, modal y permisos) tu app queda lista para emular y probar el flujo real. Cuéntame en los comentarios qué parte del flujo te resultó más útil o si vas a adaptarlo a otro caso de uso.