Compatibilidad con la cámara en varios factores de forma

Las apps para Android se ejecutan en más factores de forma que solo los teléfonos en modo vertical. Con la introducción del modo de ventanas de escritorio, las pantallas conectadas y los dispositivos plegables, tu app de cámara debe adaptarse a tamaños de ventana dinámicos, relaciones de aspecto variables y hardware externo.

Figura 1: Ejemplo de apps de cámara en diferentes pantallas.

Por qué se interrumpe la lógica del teléfono

Las apps de cámara suelen hacer suposiciones que provocan fallas críticas en entornos de varios factores de forma.

Orientación natural

  • Suposición: La orientación natural del dispositivo ROTATION_0 siempre es vertical.
  • Realidad: En tablets, pantallas internas de algunos dispositivos plegables y monitores de escritorio, ROTATION_0 suele estar en horizontal.
  • Resultado: La vista previa se rota 90 grados de forma incorrecta.
Figura 2. Visor de la cámara antes y después de aplicar la rotación correcta.

Alineación del sensor

  • Suposición: El borde largo del sensor de la cámara se alinea con el borde largo de la pantalla.
  • Realidad: Una ventana redimensionable puede ser cuadrada o horizontal, mientras que el sensor permanece fijo (por lo general, 4:3).
  • Resultado: Imágenes estiradas o distorsionadas de alguna otra manera
Figura 3: Visor de la cámara antes y después de aplicar el factor de ajuste correcto.

Densidad y tamaño de la pantalla

  • Suposición: La densidad y el tamaño de la pantalla no cambian durante el tiempo de ejecución.
  • Realidad: En los entornos de escritorio, los usuarios cambian el tamaño de las ventanas libremente.
  • Resultado: Reiniciar la sesión de la cámara en cada evento de arrastre interrumpe la experiencia del usuario y puede provocar fallas.

Solución 1: Usa intents del sistema

Si tu app necesita tomar una foto o grabar un video, pero no requiere una interfaz de cámara personalizada especializada, la mejor manera de controlar los diferentes factores de forma es iniciar la cámara del sistema preinstalada del dispositivo (consulta Intents de cámara).

El uso de un intent del sistema delega toda la experiencia de captura a la app de cámara desarrollada por el fabricante de equipos originales (OEM) del dispositivo. Esto subcontrata de manera efectiva la complejidad de la compatibilidad con factores de forma, lo que incluye lo siguiente:

  • Compatibilidad integrada con el cambio de tamaño y la rotación: La app de cámara predeterminada en una tablet o un dispositivo plegable está diseñada explícitamente por el fabricante para controlar la geometría específica de ese dispositivo. La app está diseñada para comportarse correctamente cuando el dispositivo se despliega, se rota o se coloca en modo multiventana.

  • Acceso a funciones de hardware avanzadas: Las apps de cámara del OEM tienen acceso exclusivo a algoritmos optimizados para el hardware (modo nocturno, HDR, cambio de lente específico) que son difíciles o imposibles de replicar de forma manual.

Solución 2: Usa Jetpack CameraX

CameraX es una biblioteca de Jetpack creada para facilitar el desarrollo de apps de cámara. CameraX está optimizado para los ciclos de vida y orientado a la superficie. A diferencia de Camera2, que requiere el recálculo manual de la orientación del sensor y los tamaños de la superficie cada vez que se pliega, rota o cambia de tamaño un dispositivo, CameraX controla automáticamente la reconfiguración de las sesiones de la cámara durante el cambio de tamaño en ventanas múltiples o cuando una app se mueve a una pantalla conectada, lo que garantiza que el flujo de vista previa se adapte sin interrupciones ni estiramientos.

Los componentes como PreviewView administran de forma inteligente la relación de aspecto y los tipos de escala en diferentes estados, como un dispositivo plegable que pasa de la pantalla de la cubierta a la pantalla interior, lo que te permite admitir una amplia variedad de hardware con una sola implementación coherente en lugar de una intrincada colección de casos extremos específicos del dispositivo.

Redactar

Con Jetpack Compose, usa la biblioteca androidx.camera:camera-compose dedicada. La biblioteca proporciona el elemento CameraXViewfinder componible, que está diseñado específicamente para controlar la geometría compleja del cambio de tamaño, la rotación y las relaciones de aspecto dentro del ciclo de vida de Compose.

El componente CameraXViewfinder elimina las fuentes de errores más comunes en las apps de cámara:

  • Transformación automática de coordenadas: Una de las partes más difíciles de crear una app de cámara es asignar la presión del usuario (coordenadas X e Y en pantalla) al sistema de coordenadas del sensor de la cámara (de 0 a 1, rotado de 0 a 1) para el enfoque y la medición. CameraXViewfinder proporciona un CoordinateTransformer que controla las matemáticas automáticamente, incluso cuando se cambia el tamaño de la ventana o se pliega el dispositivo.
  • Comportamiento de diseño correcto: A diferencia de SurfaceView o TextureView, CameraXViewfinder funciona correctamente con el ordenamiento en Z de Compose. Puedes superponer elementos de la IU (anillos de enfoque, controles) o aplicar modificadores (esquinas redondeadas, animaciones) sin renderizar artefactos.
  • Cambio de tamaño y relación de aspecto: CameraXViewfinder controla internamente la lógica de recorte centrado frente a ajuste centrado, lo que garantiza que la vista previa no se estire cuando se cambia el tamaño de la ventana de la app a relaciones de aspecto no estándar (por ejemplo, el modo de pantalla dividida o de ventanas de escritorio).

Objetos View

En las apps basadas en vistas, usa PreviewView o ViewFinderView. Si usas SurfaceView o TextureView directamente, debes calcular la relación de aspecto y aplicar la matriz de transformación correcta por tu cuenta.

Solución 3: Controla la orientación y el cambio de tamaño de forma dinámica

Cuando utilices APIs de la plataforma directamente, ten en cuenta la rotación del dispositivo, los reinicios de la actividad y la relación de aspecto.

Cómo dejar de usar la rotación del dispositivo

No dependas solo de Display#getRotation() o de la orientación del sensor físico para determinar el diseño de la IU.

  • Usa métricas de ventana: Determina tu diseño (IU horizontal o vertical) comparando el ancho y la altura de la ventana de la app con WindowManager#getCurrentWindowMetrics().
  • Ignorar la orientación natural: Es posible que tu app se encuentre en una ventana con forma vertical en un monitor horizontal. La orientación del dispositivo no es relevante para los límites de la IU.

Cómo evitar que se reinicie la actividad

El comportamiento predeterminado de Android destruye la actividad de tu app en los cambios de configuración (como el cambio de tamaño de la ventana). En el caso de las apps de cámara, esto aparece como un parpadeo de la pantalla o una conexión interrumpida durante las videollamadas.

Relación de aspecto y recorte

Un problema común en las ventanas de escritorio y dispositivos plegables es el estiramiento de la vista previa, en el que un feed de cámara de 4:3 se fuerza a una ventana de 16:9 o 1:1.

  • No estirar: Nunca fuerces el búfer de la cámara para que coincida exactamente con los límites de la vista si difieren las relaciones de aspecto de la vista previa y la ventana.
  • Recorte centrado (recomendado): Ajusta la escala de la vista previa para completar la dimensión más corta de la ventana y recorta el exceso. Esto garantiza que el sujeto no se distorsione y llene el encuadre.
  • Centro de ajuste (alternativa): Si es fundamental mostrar el campo de visión completo (por ejemplo, para escanear un documento), agrega barras negras en la parte superior e inferior de la vista previa dentro de la ventana.
  • Centro de ajuste (alternativa): Si es fundamental mostrar el campo de visión completo (por ejemplo, para escanear un documento), agrega barras negras en la parte superior e inferior de la vista previa dentro de la ventana.

Bonus: Compatibilidad con experiencias que priorizan los dispositivos plegables

Los dispositivos plegables no son solo teléfonos que se doblan, sino que ofrecen estados de hardware únicos que pueden mejorar fundamentalmente la forma en que los usuarios toman fotos y videos. En lugar de tratar el pliegue como un problema que se debe resolver, úsalo para crear funciones que son imposibles en dispositivos no plegables.

Modo de mesa (captura con manos libres)

El modo de mesa permite a los usuarios plegar el dispositivo por la mitad y apoyarlo sobre una superficie para realizar videollamadas prolongadas, tomar fotografías de lapso de tiempo y fotografías nocturnas de larga exposición.

Figura 5: Una app de comunicación en modo de mesa: el visor de la cámara está en la parte superior de la bisagra y los controles en la parte inferior.

Modo de pantalla posterior (selfies de alta calidad)

  • En los teléfonos plegables, las cámaras posteriores suelen tener una calidad superior a las cámaras frontales. El modo de pantalla posterior permite que el usuario despliegue el dispositivo y lo gire, usando la pequeña pantalla de la cubierta como visor en vivo para la cámara posterior principal.
  • El modo de pantalla posterior permite tomar selfies de más de 50 MP, fotos grupales ultra gran angular y vlogs de alta calidad sin necesidad de llevar equipos adicionales.

Modo de pantalla doble (vista previa del sujeto)

  • El modo Dual Screen te permite mostrar la vista previa de la cámara en ambas pantallas, la interior y la exterior, de forma simultánea. Esto es ideal para fotografiar personas, ya que los sujetos de la foto pueden verse en la pantalla exterior y ajustar su pose mientras tú encuadras la toma en la pantalla interior.
  • A diferencia del modo de pantalla trasera (que mueve toda la app), el modo de pantalla doble crea una ventana de presentación secundaria en la pantalla de la cubierta.
Figura 5: Una app de cámara en modo de pantalla doble.