Prácticas recomendadas

Apps para dispositivos plegables y multipantalla

Por lo general, las apps no deben depender de identificadores estáticos ni de una lógica que dependa de algunos IDs de visualización. En la mayoría de los casos, las apps deben cambiar de tamaño y funcionar en diferentes pantallas, y el sistema debe controlar dónde ubicarlas. Por ejemplo, para crear 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 plegado, 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 en respuesta y, 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.

Restringe el acceso a las 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 de agregar una ventana por parte de alguien que no sea el propietario genera un SecurityException. Si el sistema es propietario de la pantalla, puede agregar ventanas y, también, iniciar actividades.

Además, las entidades que se colocan 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. Como resultado, el propietario es responsable de restringir el acceso y permitir solo apps de confianza.

Además, se agregan más restricciones a las pantallas virtuales, ya que 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

Las decoraciones del sistema se pueden 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 (iniciador, 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 (este valor predeterminado 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, se usa uniqueId para la identificación de la pantalla en el atributo name, 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 establecer identifier="1" para que corresponda a 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 pantallas estáticas.

Para obtener más información, consulta: