Prácticas recomendadas

Apps para dispositivos plegables y multipantalla

Por lo general, las apps no deben basarse en identificadores estáticos ni en lógica que depende de algunos IDs de pantalla. En la mayoría de los casos, las apps deben cambiar de tamaño y funcionar en pantallas diferentes, y el sistema debe controlar dónde ubicar las apps. Por ejemplo, para compilar una experiencia nueva y única para dispositivos plegables y lanzar una app especial en la pantalla externa cuando el dispositivo está plegado.

En este caso, SystemUI (o algún otro componente del sistema) debe detectar el pliegue, determinar si es apropiado realizar una acción y, luego, iniciar la actividad objetivo y especificar un ID de pantalla externo como objetivo de inicio. Las apps no deben detectar esta acción ni realizar ninguna acción como respuesta para, luego, realizar el inicio en una pantalla específica. En otras palabras, no des por sentado que lo que funciona en un dispositivo funcionará en otros. En resumen, el código específico del dispositivo aumenta la fragmentación.

Restringir el acceso a pantallas

Si la configuración del dispositivo requiere la restricción del acceso a una o más pantallas, se recomienda usar la marca Display#FLAG_PRIVATE para designar esas pantallas como privadas. De esta manera, se restringe que todas las personas, excepto el propietario, agreguen contenido a la pantalla. Cualquier intento de iniciar una actividad o agregar una ventana por parte de cualquier persona, excepto por el propietario, dará como resultado una SecurityException. Si el sistema es propietario de la pantalla, puede agregar ventanas y, también, iniciar actividades.

Además, las entidades ubicadas en una pantalla siempre pueden acceder a ella. Si el propietario inicia una actividad en una pantalla, esta puede iniciar otras actividades en esta pantalla. Por lo tanto, el propietario es responsable de restringir el acceso y permitir solo las apps de confianza.

Además, se agregan más restricciones a las pantallas virtuales porque cualquier app puede crear una sin que el usuario la vea. Si el sistema no es el propietario de la pantalla virtual, solo se permiten actividades con allowEmbedded, y el llamador debe tener el permiso ACTIVITY_EMBEDDING.

Para obtener más información, consulta:

  • ActivityStackSupervisor#isCallerAllowedToLaunchOnDisplay()
  • ActivityDisplay#isUidPresent()
  • DisplayManagerService#isUidPresentOnDisplay()

Para controlar de forma condicional los inicios de actividad, usa LaunchParamsController, que intercepta todos los inicios de actividad y permite que un componente del sistema modifique los parámetros que se usan para el inicio. Esta función está disponible en system_server.

Cómo configurar la configuración de ventanas de la pantalla y las decoraciones del sistema

La decoración del sistema se puede configurar por pantalla en DisplayWindowSettings. Una implementación de dispositivo puede proporcionar una configuración predeterminada en /data/system/display_settings.xml.

Este valor determina si las decoraciones del sistema (selector de aplicaciones, fondo de pantalla, barra de navegación y otras ventanas de decoración) y el IME aparecen en una pantalla. Para obtener más información, consulta DisplayWindowSettings#shouldShowSystemDecorsLocked() y DisplayWindowSettings#shouldShowImeLocked().

Para identificar la pantalla, usa un ID único (esta configuración predeterminada usa DisplayInfo#uniqueId) o un ID de puerto físico para pantallas de hardware (consulta DisplayInfo#address).

Por ejemplo, el siguiente ejemplo de configuración de la pantalla habilita las decoraciones del sistema y el IME en una pantalla simulada:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<display-settings>
<config identifier="0" />
<display
  name="overlay:1"
  shouldShowSystemDecors="true"
  shouldShowIme="true" />
</display-settings>

En el ejemplo anterior, uniqueId se usa para la identificación de pantalla en el atributo de nombre, que para una pantalla simulada es overlay:1. Para una pantalla integrada, un valor de muestra puede ser "local:45354385242535243453". Otra opción es usar la información del puerto de hardware y configurar identifier="1" para que corresponda con DisplayWindowSettings#IDENTIFIER_PORT y, luego, actualizar el nombre para usar el formato "port:<port_id>":

<?xmlversion='1.0' encoding='utf-8' standalone='yes' ?>
<display-settings>
<config identifier="1" />
<display
  name="port:12345"
  shouldShowSystemDecors="true"
  shouldShowIme="true" />
</display-settings>

Para obtener más información, consulta Identificadores de visualización estáticos.

Para obtener más información, consulta: