Las pantallas conectadas extienden la experiencia de ventanas de escritorio a los teléfonos estándar, lo que les brinda a los usuarios acceso a pantallas grandes desde sus dispositivos móviles. Esta capacidad abre nuevas posibilidades para la interacción con la app y la productividad del usuario.
Todas las funciones únicas del modo de ventanas de escritorio se aplican a las pantallas conectadas. Cuando conectas un teléfono a una pantalla, el estado del teléfono no cambia y se inicia una sesión de escritorio en blanco en la pantalla conectada. El dispositivo y la pantalla actúan como dos sistemas individuales, con apps específicas para cada pantalla.
Si conectas un dispositivo compatible con el modo de ventanas de escritorio, como una tablet, a un monitor externo, la sesión de escritorio se extenderá a ambas pantallas. Luego, las dos pantallas funcionan como un solo sistema continuo. Esta configuración permite que las ventanas, el contenido y el cursor se muevan libremente entre las dos pantallas.
Para admitir pantallas conectadas de manera eficaz, debes prestar atención a varios aspectos del diseño y la implementación de tu app. Las siguientes prácticas recomendadas garantizan una experiencia del usuario fluida y productiva.
Cómo controlar cambios en la pantalla dinámica
Muchas apps se compilan con la suposición de que el objeto Display y sus características no cambiarán durante el ciclo de vida de la app. Sin embargo, cuando un usuario conecta o desconecta un monitor externo, o incluso mueve una ventana de la app entre pantallas, el objeto Display subyacente asociado con el contexto o la ventana de tu app puede cambiar. Las propiedades de la pantalla, como el tamaño, la resolución, la frecuencia de actualización, la compatibilidad con HDR y la densidad, pueden ser diferentes. Si codificas valores de forma rígida según la pantalla del teléfono, por ejemplo, es probable que tus diseños se interrumpan en una pantalla externa.
Las pantallas externas también pueden tener densidades de píxeles muy diferentes. Debes asegurarte de que tu app responda correctamente a los cambios de densidad. Esto implica usar píxeles independientes de la densidad (dp) para los diseños, proporcionar recursos específicos para la densidad y garantizar que la IU se ajuste de forma adecuada.
Si una actividad se ejecuta en una pantalla externa cuando esta se desconecta, el sistema la mueve a la pantalla principal. El movimiento activa cambios de configuración, como cambios en el tamaño y la densidad de la pantalla, que pueden hacer que se vuelva a crear la actividad. Tu app debe controlar el cambio de configuración guardando y restableciendo el estado de la IU para evitar la pérdida de datos o una experiencia del usuario confusa.
Usa el contexto adecuado
Usar el contexto correcto es crucial en los entornos de pantallas múltiples. Cuando se accede a recursos, el contexto de la actividad (que se muestra) difiere del contexto de la aplicación (que no se muestra).
El contexto de la actividad contiene información sobre la pantalla y siempre se ajusta de acuerdo con el área de visualización donde aparece la actividad. Esto te permite obtener la información correcta sobre la densidad de la pantalla o las métricas de la ventana de tu app. Siempre usa el contexto de la actividad (u otro contexto basado en la IU) para obtener información sobre la ventana o la pantalla actual. Esto también afecta algunas APIs del sistema que usan información del contexto.
En Jetpack Compose, puedes acceder a información específica de la pantalla con objetos CompositionLocal, como LocalConfiguration.current y LocalDensity.current. Cuando una actividad o una ventana se mueven entre pantallas, cambia la configuración del dispositivo, lo que activa la recomposición con nuevas métricas de pantalla. Los objetos CompositionLocal permiten que tu IU se adapte sin problemas.
Obtén información de la pantalla
Puedes usar la clase Display para obtener información como el tamaño, la densidad o las marcas de la pantalla. Usa el servicio del sistema DisplayManager para obtener las pantallas disponibles. Para identificar pantallas externas, filtra el Display.DEFAULT_DISPLAY, que suele ser la pantalla integrada del teléfono o la tablet:
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val displays = displayManager.getDisplays()
// The default display is 0. External displays have other IDs.
val externalDisplays = displays.filter { it.displayId != Display.DEFAULT_DISPLAY }
Administra el inicio y la configuración de la actividad
Con las pantallas conectadas, las apps pueden especificar en qué pantalla se deben ejecutar cuando se inician o cuando crean otra actividad. Este comportamiento depende del modo de inicio de la actividad definido en el archivo de manifiesto y de las opciones y los marcadores de intent establecidos por la entidad que inicia la actividad.
Cuando una actividad se traslada a una pantalla secundaria, tu app puede experimentar una actualización de contexto, un cambio de tamaño de ventana, y modificaciones en la configuración y los recursos. Si la actividad controla el cambio de configuración, se le notificará en onConfigurationChanged(). De lo contrario, se reinicia la actividad.
Si el modo de inicio seleccionado para una actividad permite varias instancias, el inicio en una pantalla secundaria puede crear una nueva instancia de la actividad. Ambas actividades se reanudan al mismo tiempo, lo que puede ser beneficioso en ciertos casos de multitarea.
Puedes iniciar una actividad en una pantalla en particular con ActivityOptions. Ten en cuenta que launchDisplayId requiere Android 8 (nivel de API 26) o versiones posteriores.
// Get DisplayManager and find the first external display.
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val externalDisplayId = displayManager.displays
.firstOrNull { it.displayId != Display.DEFAULT_DISPLAY }
?.displayId
// If an external display is found, launch the activity on it.
if (externalDisplayId != null) {
val intent = Intent(this, MySecondaryActivity::class.java)
val options = ActivityOptions.makeBasic()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
options.launchDisplayId = externalDisplayId
}
startActivity(intent, options.toBundle())
} else {
// Optionally, handle the case where no external display is connected.
}
Evita las listas de entidades permitidas de dispositivos
A veces, las apps restringen la IU y las funciones para pantallas grandes a dispositivos seleccionados a través de una lista de entidades permitidas o verificando BUILD.MODEL y el tamaño de pantalla integrado. Este enfoque no es eficaz para las pantallas conectadas, ya que prácticamente cualquier dispositivo se puede conectar a una pantalla grande, y el modelo del dispositivo no cambia cuando se conecta una pantalla externa.
En lugar de usar listas de entidades permitidas o verificar BUILD.MODEL y el tamaño de pantalla integrado, verifica las métricas de la ventana o las capacidades del dispositivo durante el tiempo de ejecución para tomar decisiones sobre la IU. Usa las APIs de Jetpack WindowManager o las clases de tamaño de ventana para compilar diseños responsivos y adaptables para varios tamaños y densidades de pantalla.
Admite periféricos externos
Cuando los usuarios se conectan a una pantalla externa, suelen crear un entorno más parecido al de un escritorio. Esto suele implicar el uso de teclados, mouses, paneles táctiles, cámaras web, micrófonos y bocinas externos. Debes asegurarte de que tu app funcione sin problemas con estos periféricos. Esto incluye el control de combinaciones de teclas, la administración de las interacciones del puntero del mouse, la compatibilidad correcta con cámaras o micrófonos externos y el respeto del enrutamiento de salida de audio. Para obtener más detalles, consulta Compatibilidad de entrada en pantallas grandes.
Mejora la productividad de los usuarios
Las pantallas conectadas brindan una oportunidad significativa para mejorar la productividad del usuario. Ahora tienes las herramientas para compilar apps para dispositivos móviles que pueden ofrecer experiencias comparables a las de las aplicaciones para computadoras de escritorio. Considera implementar las siguientes funciones para aumentar la productividad de los usuarios:
- Permite a los usuarios abrir varias instancias de la misma app, lo que resulta muy útil para tareas como comparar documentos, administrar diferentes conversaciones o ver varios archivos de forma simultánea.
- Permite que los usuarios compartan datos enriquecidos dentro y fuera de tu app con la función de arrastrar y soltar.
- Implementa un sistema de administración de estados sólido para ayudar a los usuarios a mantener su flujo de trabajo en los cambios de configuración.
Si sigues estos lineamientos y utilizas los ejemplos de código proporcionados, podrás crear apps que se adapten sin problemas a las pantallas conectadas y ofrecer a los usuarios una experiencia más enriquecida y productiva.