Las actualizaciones realizadas en estas áreas específicas de visualización se proporcionan a continuación:
- decoraciones del sistema
- Ventanas de decoración de la interfaz de usuario del sistema
- Lanzacohetes
- Fondos de pantalla
decoraciones del sistema
Android 10 agrega soporte para configurar pantallas secundarias para mostrar ciertas decoraciones del sistema, como fondo de pantalla, barra de navegación y lanzador. De manera predeterminada, la pantalla principal muestra todas las decoraciones del sistema y las pantallas secundarias muestran las habilitadas opcionalmente. La compatibilidad con un Editor de métodos de entrada (IME) se puede configurar por separado de otras decoraciones del sistema.
Use DisplayWindowSettings#setShouldShowSystemDecorsLocked()
para agregar soporte para decoraciones del sistema en una pantalla específica o proporcione un valor predeterminado en /data/system/display_settings.xml
. Para ver ejemplos, consulte Configuración de la ventana de visualización .
Implementación
DisplayWindowSettings#setShouldShowSystemDecorsLocked()
también se expone en WindowManager#setShouldShowSystemDecors()
para realizar pruebas. La activación de este método con la intención de habilitar las decoraciones del sistema no agrega ventanas de decoración que antes faltaban ni las elimina si estaban presentes anteriormente. En la mayoría de los casos, el cambio de la compatibilidad con las decoraciones del sistema surte efecto completo solo después de reiniciar el dispositivo.
Las comprobaciones de la compatibilidad con las decoraciones del sistema en el código base de WindowManager suelen pasar por DisplayContent#supportsSystemDecorations()
mientras que las comprobaciones de servicios externos (como la interfaz de usuario del sistema para comprobar si se debe mostrar la barra de navegación) usan WindowManager#shouldShowSystemDecors()
. Para comprender qué se controla con esta configuración, explore los puntos de llamada de estos métodos.
Ventanas de decoración de la interfaz de usuario del sistema
Android 10 agrega compatibilidad con la ventana de decoración del sistema solo para la barra de navegación, porque la barra de navegación es esencial para navegar entre actividades y aplicaciones. De forma predeterminada, la barra de navegación muestra las prestaciones de Atrás y Inicio. Esto se incluye solo si la pantalla de destino admite decoraciones del sistema (consulte DisplayWindowSettings
).
La barra de estado es una ventana del sistema más complicada, porque también contiene Sombra de notificación, Configuración rápida y Pantalla de bloqueo. En Android 10, la barra de estado no es compatible con las pantallas secundarias. Por lo tanto, las notificaciones, la configuración y un bloqueo completo del teclado solo están disponibles en la pantalla principal.
La ventana del sistema Resumen/Recientes no es compatible con las pantallas secundarias. En Android 10, AOSP solo muestra Recientes en la pantalla predeterminada y contiene actividades de todas las pantallas. Cuando se inicia desde Recientes, una actividad que estaba en una pantalla secundaria se trae al frente en esa pantalla, de manera predeterminada. Este enfoque tiene algunos problemas conocidos, como no actualizarse inmediatamente cuando las aplicaciones aparecen en otras pantallas.
Implementación
Para implementar características adicionales de la interfaz de usuario del sistema, los fabricantes de dispositivos deben usar un solo componente de la interfaz de usuario del sistema que escuche la adición/eliminación de pantallas y presente el contenido apropiado.
Un componente de la interfaz de usuario del sistema que admita pantallas múltiples (MD) debe manejar los siguientes casos:
- Inicialización de múltiples pantallas al inicio
- Pantalla añadida en tiempo de ejecución
- Pantalla eliminada en tiempo de ejecución
Cuando la interfaz de usuario del sistema detecta la adición de una pantalla antes de WindowManager, crea una condición de carrera. Esto se puede evitar implementando una devolución de llamada personalizada desde WindowManager a la interfaz de usuario del sistema cuando se agrega una pantalla en lugar de suscribirse a los eventos DisplayManager .DisplayListener
. Para ver una implementación de referencia, consulte CommandQueue.Callbacks#onDisplayReady
para compatibilidad con la barra de navegación y WallpaperManagerInternal#onDisplayReady
para fondos de pantalla.
Además, Android 10 proporciona estas actualizaciones:
- La clase
NavigationBarController
controla toda la funcionalidad específica de las barras de navegación. - Para ver una barra de navegación personalizada, consulte
CarStatusBar
. -
TYPE_NAVIGATION_BAR
ya no está restringido a una sola instancia y se puede usar por pantalla. -
IWindowManager#hasNavigationBar()
se actualizó para incluir el parámetrodisplayId
solo para la interfaz de usuario del sistema.
Lanzacohetes
En Android 10, cada pantalla configurada para admitir las decoraciones del sistema tiene una pila de inicio dedicada para las actividades del iniciador con el tipo WindowConfiguration#ACTIVITY_TYPE_HOME
de forma predeterminada. Cada pantalla usa una instancia separada de la actividad del iniciador.
Figura 1. Ejemplo de iniciador de múltiples pantallas para platform/development/samples/MultiDisplay
La mayoría de los lanzadores existentes no admiten varias instancias y no están optimizados para pantallas de gran tamaño. Además, a menudo se espera un tipo diferente de experiencia en pantallas secundarias/externas. Para proporcionar una actividad dedicada para las pantallas secundarias, Android 10 presenta la categoría SECONDARY_HOME
en los filtros de intenciones. Las instancias de esta actividad se utilizan en todas las pantallas que admiten decoraciones del sistema, una por pantalla.
<activity> ... <intent-filter> <category android:name="android.intent.category.SECONDARY_HOME" /> ... </intent-filter> </activity>
La actividad debe tener un modo de inicio que no impida múltiples instancias y se espera que se adapte a diferentes tamaños de pantalla. El modo de inicio no puede ser singleInstance
o singleTask
.
Implementación
En Android 10, RootActivityContainer#startHomeOnDisplay()
selecciona automáticamente el componente deseado y la intención según la pantalla donde se inicia la pantalla de inicio. RootActivityContainer#resolveSecondaryHomeActivity()
contiene la lógica para buscar el componente de actividad del iniciador según el iniciador seleccionado actualmente y puede usar el valor predeterminado del sistema, si es necesario (consulte ActivityTaskManagerService#getSecondaryHomeIntent()
).
Restricciones de seguridad
Además de las restricciones que se aplican a las actividades en pantallas secundarias, para evitar la posibilidad de que una aplicación malintencionada cree una pantalla virtual con las decoraciones del sistema habilitadas y lea información confidencial del usuario desde la superficie, el lanzador aparece solo en pantallas virtuales propiedad del sistema. El iniciador no muestra contenido en pantallas virtuales que no sean del sistema.
Fondos de pantalla
En Android 10 (y superior), los fondos de pantalla son compatibles con las pantallas secundarias:
Figura 2. Fondo de pantalla en vivo en pantallas internas (arriba) y externas (abajo)
Los desarrolladores pueden declarar la compatibilidad con la función de fondo de pantalla proporcionando android:supportsMultipleDisplays="true"
en la definición XML de WallpaperInfo
. También se espera que los desarrolladores de fondos de pantalla carguen activos usando el contexto de visualización en WallpaperService.Engine#getDisplayContext()
.
El marco crea una instancia de WallpaperService.Engine
por pantalla, por lo que cada motor tiene su propia superficie y contexto de visualización. El desarrollador debe asegurarse de que cada motor pueda dibujar de forma independiente, a diferentes velocidades de cuadro, respetando VSYNC.
Seleccionar fondos de pantalla para pantallas individuales
Android 10 no brinda compatibilidad directa con la plataforma para seleccionar fondos de pantalla para pantallas individuales. Para lograr esto, se necesita un identificador de pantalla estable para conservar la configuración del fondo de pantalla por pantalla. Display#getDisplayId()
es dinámico, por lo que no hay garantía de que una pantalla física tenga el mismo ID después de reiniciar.
Sin embargo, Android 10 agregó DisplayInfo.mAddress
, que contiene identificadores estables para pantallas físicas y se puede usar para una implementación completa en el futuro. Desafortunadamente, es demasiado tarde para implementar la lógica para Android 10. La solución sugerida:
- Use la API
WallpaperManager
para configurar los fondos de pantalla. -
WallpaperManager
se obtiene de un objeto deContext
, y cada objeto deContext
tiene información sobre la visualización correspondiente (Context#getDisplay()/getDisplayId()
). Por lo tanto, puede obtenerdisplayId
de una instancia deWallpaperManager
sin agregar nuevos métodos. - En el lado del marco, use
displayId
obtenido de un objetoContext
y asígnelo a un identificador estático (como un puerto de una pantalla física). Use el identificador estático para conservar el fondo de pantalla elegido.
Esta solución utiliza las implementaciones existentes para los selectores de papel tapiz. Si se abrió en una pantalla específica y usa el contexto correcto, entonces cuando llama para configurar un fondo de pantalla, el sistema puede identificar automáticamente la pantalla.
Si es necesario establecer un fondo de pantalla para una pantalla que no sea la pantalla actual, cree un nuevo objeto de Context
para la pantalla de destino ( Context#createDisplayContext
) y obtenga la instancia de WallpaperManager
de esa pantalla.
Restricciones de seguridad
El sistema no mostrará fondos de pantalla en pantallas virtuales que no sean de su propiedad. Esto se debe a un problema de seguridad de que una aplicación malintencionada podría crear una pantalla virtual con soporte de decoraciones del sistema habilitado y leer información confidencial del usuario desde la superficie (como una foto personal).
Implementación
En Android 10, las IWallpaperConnection#attachEngine()
e IWallpaperService#attach()
aceptan el parámetro displayId
para crear conexiones por pantalla. WallpaperManagerService.DisplayConnector
encapsula una conexión y un motor de papel tapiz por pantalla. En WindowManager, los controladores de papel tapiz se crean para cada objeto DisplayContent
en la construcción en lugar de un solo WallpaperController
para todas las pantallas.
Algunas de las implementaciones públicas del método WallpaperManager
(como WallpaperManager#getDesiredMinimumWidth()
) se actualizaron para calcular y proporcionar información para las pantallas correspondientes. Se agregaron WallpaperInfo#supportsMultipleDisplays()
y un atributo de recurso correspondiente, para que los desarrolladores de aplicaciones puedan informar qué fondos de pantalla están listos para varias pantallas.
Si el servicio de fondo de pantalla que se muestra en la pantalla predeterminada no admite varias pantallas, el sistema muestra el fondo de pantalla predeterminado en las pantallas secundarias.
Figura 3. Lógica alternativa de fondo de pantalla para pantallas secundarias