The Android Developer Challenge is back! Submit your idea before December 2.

Compatibilidad multiventana

Android 7.0 agrega compatibilidad con la visualización de más de una aplicación a la vez. En dispositivos portátiles, se pueden ejecutar dos aplicaciones una al lado de la otra o una por encima de la otra en el modo de pantalla dividida. En dispositivos de TV, las aplicaciones pueden usar el modo pantalla en pantalla para continuar la reproducción de video mientras los usuarios interactúan con otra aplicación.

Si tu aplicación está dirigida a Android 7.0 (nivel de API 24) o superior, puedes configurar el modo en que tu aplicación gestiona la visualización multiventana. Por ejemplo, puedes especificar las dimensiones mínimas permitidas de tu actividad. También puedes inhabilitar la visualización multiventana para tu aplicación asegurándote de que el sistema solo muestre tu aplicación en el modo de pantalla completa.

Recientes

Android permite que varias aplicaciones compartan la pantalla al mismo tiempo. Por ejemplo, un usuario podría dividir la pantalla y ver una página web a la izquierda mientras escribe un correo electrónico a la derecha. La experiencia del usuario depende de la versión del SO Android y del tipo de dispositivo:

  • Los dispositivos portátiles con Android 7.0 ofrecen el modo de pantalla dividida. En este modo, el sistema ocupa la pantalla con dos aplicaciones y las muestra una al lado de la otra o una encima de la otra. El usuario puede arrastrar la línea que divide las dos aplicaciones para ver una más grande que la otra.
  • A partir de Android 8.0, las apps pueden habilitar de forma automática el modo pantalla en pantalla. Esto les permite continuar mostrando contenido mientras el usuario explora otras apps o interactúa con ellas.
  • Los fabricantes de dispositivos más grandes pueden optar por habilitar el modo de forma libre, en el que el usuario puede modificar libremente el tamaño de cada actividad. Si el fabricante habilita está función, el dispositivo ofrecerá el modo de forma libre además del modo de pantalla dividida.

Figura 1: Dos aplicaciones ejecutándose una al lado de la otra en el modo de pantalla dividida

El usuario puede cambiar al modo multiventana de la siguiente manera:

  • Si el usuario abre la pantalla Recientes y presiona durante un momento el título de una actividad, puede arrastrar esa actividad a una parte resaltada de la pantalla para llevarla al modo multiventana.
  • Si el usuario presiona durante un momento el botón Recientes, el dispositivo coloca la actividad actual en el modo multiventana y abre la pantalla Recientes para permitirle al usuario seleccionar otra actividad para compartir la pantalla.

Los usuarios pueden arrastrar y soltar datos de una actividad a otra mientras las actividades comparten la pantalla.

Ciclo de vida en el modo multiventana

El modo multiventana no cambia el ciclo de vida de la actividad.

En el modo multiventana, solo la actividad con la que el usuario interactuó más recientemente está activa en un momento determinado. Esta actividad se considera principal y es la única actividad en el estado de RESUMED. Todas las demás actividades visibles son STARTED, pero no RESUMED. No obstante, el sistema les da a esas actividades visibles pero no pausadas una prioridad más alta que a las que no están visibles. Si el usuario interactúa con una de las actividades visibles, se reanuda esa actividad y la actividad principal anterior pasa al estado STARTED.

Nota: En el modo multiventana, una aplicación puede no estar en el estado RESUMED aunque sea visible para el usuario. Una aplicación podría necesitar seguir ejecutándose mientras no esté en primer plano. Por ejemplo, una aplicación de reproducción de video en este estado debería seguir mostrando su contenido. Por este motivo, recomendamos que las actividades que reproduzcan videos no pausen la reproducción en respuesta al evento del ciclo de vida ON_PAUSE. En su lugar, la actividad debe comenzar a reproducirse en respuesta a ON_START y pausar la reproducción en respuesta a ON_STOP. Si gestionas los eventos del ciclo de vida de forma directa en lugar de utilizar el paquete Lifecycle, detén la reproducción de video en tu controlador onStop() y reanuda la reproducción en onStart().

Cuando el usuario coloca una aplicación en el modo multiventana, el sistema notifica a la actividad de un cambio de configuración, tal como se especifica en Cómo controlar los cambios de configuración. Esto también sucede cuando el usuario modifica el tamaño de la aplicación o coloca la aplicación nuevamente en el modo de pantalla completa. Básicamente, este cambio tiene las mismas consecuencias en el ciclo de vida de la actividad que cuando el sistema notifica a la aplicación que el dispositivo cambió del modo vertical al horizontal, excepto porque se modifican las dimensiones del dispositivo en lugar de intercambiarse solamente. Como se aborda en Cómo controlar cambios de configuración, tu actividad puede administrar el cambio de configuración por sí misma o puede permitir que el sistema destruya la actividad y la vuelva a crear con las nuevas dimensiones.

Si el usuario cambia el tamaño de una ventana y la agranda en cualquier dirección, el sistema modifica el tamaño de la actividad para que coincida con la acción del usuario y emite cambios de configuración según sea necesario. Si la aplicación se retrasa en el trazado de áreas recientemente expuestas, el sistema rellena esas áreas con el color especificado por el atributo windowBackground o por el atributo de estilo predeterminado windowBackgroundFallback.

Cómo configurar tu aplicación para el modo multiventana

Si tu aplicación está orientada a un nivel de API 24 o superior, puedes configurar si quieres que las actividades de tu aplicación admitan la visualización multiventana y cómo quieres que lo hagan. Puedes establecer atributos en tu manifiesto para controlar el tamaño y el diseño. La configuración de atributos de una actividad raíz se aplica a todas las actividades de su pila de tareas. Por ejemplo, si android:resizeableActivity está configurado en "true" para la actividad raíz, se puede modificar el tamaño de todas las actividades de la pila de tareas.

Nota: Si creas una aplicación para varias orientaciones con un nivel de API 23 o inferior, y el usuario utiliza la aplicación en el modo multiventana, el sistema redimensiona la aplicación por la fuerza. El sistema presenta un cuadro de diálogo en el que se le advierte al usuario que la aplicación puede comportarse de forma inesperada. El sistema no modifica el tamaño de aplicaciones con orientación fija; si el usuario intenta abrir una aplicación con orientación fija en el modo multiventana, la aplicación ocupará toda la pantalla.

android:resizeableActivity

Establece este atributo en el elemento <activity> o <application> de tu manifiesto para habilitar o inhabilitar la visualización en el modo multiventana:

android:resizeableActivity=["true" | "false"]

Si este atributo se establece en "true", la actividad puede iniciarse en los modos de pantalla dividida y forma libre. Si el atributo se establece en "false", la actividad no admite el modo multiventana. Si el valor es "false", y el usuario intenta iniciar la actividad en el modo multiventana, la actividad ocupará toda la pantalla.

Si tu app está orientada al nivel de API 24, pero no especificas un valor para este atributo, el valor predeterminado del atributo será "true".

android:supportsPictureInPicture

Establece este atributo en el nodo <activity> de tu manifiesto para indicar si la actividad admite la visualización de pantalla en pantalla. Este atributo se ignora si android:resizeableActivity es "false".

android:supportsPictureInPicture=["true" | "false"]

Atributos de diseño

Con Android 7.0, el elemento de manifiesto <layout> admite varios atributos que afectan cómo se comporta una actividad en el modo multiventana:

android:defaultWidth
Ancho predeterminado de la actividad cuando se inicia en modo de forma libre.
android:defaultHeight
Altura predeterminada de la actividad cuando se inicia en modo de forma libre.
android:gravity
Ubicación inicial de la actividad cuando se inicia en el modo de forma libre. Consulta la referencia Gravity para obtener valores adecuados.
android:minHeight, android:minWidth
Altura y ancho mínimos para la actividad tanto en el modo de pantalla dividida como en el modo de forma libre. Si el usuario mueve la línea divisoria en el modo de pantalla dividida para reducir el tamaño respecto del tamaño mínimo especificado, el sistema recorta la actividad para ajustarla a los requisitos del usuario.

Por ejemplo, el siguiente código muestra cómo especificar el tamaño y la ubicación predeterminados de una actividad, y su tamaño mínimo, cuando la actividad se visualiza en el modo de forma libre:

<activity android:name=".MyActivity">
    <layout android:defaultHeight="500dp"
          android:defaultWidth="600dp"
          android:gravity="top|end"
          android:minHeight="450dp"
          android:minWidth="300dp" />
</activity>

Cómo ejecutar tu aplicación en el modo multiventana

A partir de Android 7.0, el sistema ofrece funcionalidad para admitir aplicaciones que pueden ejecutarse en el modo multiventana.

Funciones inhabilitadas en el modo multiventana

Ciertas funciones están inhabilitadas o se ignoran cuando un dispositivo se encuentra en el modo multiventana, ya que no resultan útiles para una actividad que podría estar compartiendo la pantalla del dispositivo con otras actividades o aplicaciones. Esas funciones incluyen las siguientes:

  • Algunas opciones de personalización de la IU del sistema están inhabilitadas; por ejemplo, las aplicaciones no pueden ocultar la barra de estado si no se están ejecutando en el modo de pantalla completa.
  • El sistema ignora los cambios en el atributo android:screenOrientation.

Notificación y consulta de cambios en el modo multiventana

Activity ofrece los siguientes métodos para admitir la visualización multiventana.

isInMultiWindowMode()
Realiza una llamada para averiguar si la actividad está en el modo multiventana.
isInPictureInPictureMode()
Realiza una llamada para averiguar si la actividad está en el modo de pantalla en pantalla.

Nota: El modo de pantalla en pantalla es un caso especial del modo multiventana. Si myActivity.isInPictureInPictureMode() muestra un valor "true", myActivity.isInMultiWindowMode() también muestra un valor "true".

onMultiWindowModeChanged()
El sistema llama a este método siempre que la actividad entra en el modo multiventana o sale de él. El sistema le pasa al método un valor "true" si la actividad entra en el modo multiventana y "false" si sale de él.
onPictureInPictureModeChanged()
El sistema llama a este método siempre que la actividad entra en el modo de pantalla en pantalla o sale de él. El sistema le pasa al método un valor "true" si la actividad entra en el modo de pantalla en pantalla y "false" si sale de él.

La clase Fragment expone versiones de muchos de estos métodos, como Fragment.onMultiWindowModeChanged().

Cómo entrar en el modo de pantalla en pantalla

Para que una actividad entre en el modo de pantalla en pantalla, debes llamar a Activity.enterPictureInPictureMode(). Este método no tiene efecto si el dispositivo no admite el modo de imagen en imagen. Para obtener más información, consulta la documentación de pantalla en pantalla.

Inicia nuevas actividades en el modo multiventana

Cuando inicias una nueva actividad, puedes indicarle al sistema que se debe mostrar adyacente a la actual si es posible. Para hacer esto, usa el marcador de intent FLAG_ACTIVITY_LAUNCH_ADJACENT. Pasar este marcador requiere el siguiente comportamiento:

  • Si el dispositivo está en el modo de pantalla dividida, el sistema intenta crear la nueva actividad junto a la actividad que lo inició, de modo que las dos actividades compartan la pantalla. No se garantiza que el sistema pueda hacerlo, pero ubicará las actividades de forma adyacente si es posible.
  • Si el dispositivo no está en el modo de pantalla dividida, este marcador no tendrá efecto.

Si un dispositivo está en el modo de forma libre e inicias una nueva actividad, puedes especificar las dimensiones y la ubicación de la pantalla de la nueva actividad llamando a ActivityOptions.setLaunchBounds(). Este método no tiene efecto si el dispositivo no está en el modo multiventana.

Nota: Si inicias una actividad en una pila de tareas, esa actividad reemplaza la actividad en pantalla y hereda todas sus propiedades multiventana. Si quieres iniciar la nueva actividad en una ventana independiente en el modo multiventana, debes iniciarla en una nueva pila de tareas.

Cómo agregar compatibilidad con arrastrar y soltar

Los usuarios pueden arrastrar y soltar datos de una actividad a otra mientras las dos actividades comparten la pantalla. (Antes de Android 7.0, los usuarios solo podían arrastrar y soltar datos dentro de una sola actividad). Por este motivo, te recomendamos que agregues la funcionalidad de arrastrar y soltar a tu aplicación si aún no la admite.

DragAndDropPermissions
Objeto token responsable de especificar los permisos otorgados a la aplicación que recibe datos mediante la funcionalidad de arrastrar y soltar.
View.startDragAndDrop()
Alias de View.startDrag(). Para habilitar la funcionalidad de arrastrar y soltar entre diferentes actividades, pasa el marcador DRAG_FLAG_GLOBAL. Si necesitas otorgar permisos de URI a la actividad receptora, pasa los nuevos marcadores DRAG_FLAG_GLOBAL_URI_READ o DRAG_FLAG_GLOBAL_URI_WRITE según corresponda.
View.cancelDragAndDrop()
Cancela una operación de arrastrar actualmente en curso. Solo puede ser llamado por la aplicación que originó la operación de arrastrar.
View.updateDragShadow()
Reemplaza la sombra del arrastre por una operación de arrastrar actualmente en curso. Solo puede ser llamado por la aplicación que originó la operación de arrastrar.
Activity.requestDragAndDropPermissions()
Solicita los permisos para los URI de contenido que se pasan con el ClipData incluido en un DragEvent.

Cómo probar la compatibilidad de tu aplicación con el modo multiventana

Independientemente de si tu aplicación está dirigida al nivel de API 24 o superior, debes verificar cómo se comporta en el modo multiventana en caso de que un usuario intente iniciarla en un dispositivo que ejecute Android 7.0 o una versión posterior.

Cómo configurar un dispositivo de prueba

Si un dispositivo ejecuta Android 7.0 o una versión posterior, automáticamente admite el modo de pantalla dividida.

Si tu app está orientada al nivel de API 23 o inferior

Si tu app está orientada al nivel de API 23 o inferior, y el usuario intenta usar la aplicación en el modo multiventana, el sistema cambia el tamaño de la aplicación de forma forzada, a menos que la aplicación declare una orientación fija.

Si tu aplicación no declara una orientación fija, debes iniciar tu aplicación en un dispositivo con Android 7.0 o una versión posterior e intentar colocar la aplicación en el modo de pantalla dividida. Cuando se modifique el tamaño de la aplicación de forma forzada, verifica que la experiencia de usuario sea aceptable.

Si la aplicación declara una orientación fija, debes intentar colocar la aplicación en el modo multiventana. Cuando lo hagas, verifica que la aplicación continúe en el modo de pantalla completa.

Si admites el modo multiventana

Si tu aplicación está dirigida al nivel de API 24 o superior, y no inhabilita la compatibilidad multiventana, verifica el siguiente comportamiento tanto en el modo de pantalla dividida como en el de forma libre.

  • Inicia la aplicación en el modo de pantalla completa y luego cambia al modo multiventana presionando durante un momento el botón Recientes. Verifica que la aplicación pase de un modo a otro correctamente.
  • Inicia la aplicación directamente en el modo multiventana y verifica que se inicie correctamente. Puedes iniciar una aplicación en el modo multiventana presionando el botón Recientes y, luego, presionar durante un momento la barra de título de la aplicación y arrastrarla a una de las áreas resaltadas de la pantalla.
  • Cambia el tamaño de tu aplicación al modo de pantalla dividida arrastrando la línea divisoria. Verifica que la aplicación cambie de tamaño sin bloquearse y que estén visibles los elementos necesarios de la IU.
  • Si especificaste dimensiones mínimas para tu aplicación, intenta cambiar el tamaño a dimensiones más bajas que las especificadas. Verifica que no puedas modificar el tamaño de la aplicación para que sea más pequeña que la dimensión mínima especificada.
  • En todas las pruebas, verifica que el rendimiento de la aplicación sea aceptable. Por ejemplo, verifica que la actualización de la IU después de cambiar el tamaño de la aplicación no tarde mucho.

Lista de comprobación de pruebas

Para verificar el rendimiento de tu aplicación en el modo multiventana, realiza las siguientes operaciones. Debes probar estas operaciones tanto en el modo de pantalla dividida como en el modo multiventana, excepto cuando se indique algo diferente.

  • Ingresa en el modo multiventana y luego sal.
  • Pasa de tu aplicación a otra y verifica que la aplicación se comporte correctamente mientras esté visible pero no activa. Por ejemplo, si tu aplicación está reproduciendo un video, comprueba que el video se siga reproduciendo mientras el usuario interactúa con otra aplicación.
  • En el modo de pantalla dividida, prueba a mover la barra divisora para agrandar y achicar la aplicación. Realiza estas operaciones en las configuraciones una al lado de la otra y una encima de la otra. Verifica que la aplicación no se bloquee, que las funcionalidades necesarias estén visibles y que la operación de cambio de tamaño no tarde mucho.
  • Realiza varias operaciones de cambio de tamaño en una sucesión rápida. Verifica que tu aplicación no falle ni pierda memoria. Para obtener información sobre cómo comprobar el uso de la memoria de tu aplicación, utiliza el generador de perfiles de memoria de Android Studio.
  • Usa tu aplicación en diferentes configuraciones de ventanas y verifica que se comporte correctamente. Verifica que el texto sea legible y que los elementos de la IU sean lo suficientemente grandes para interactuar con ellos.

Si inhabilitaste la compatibilidad con el modo multiventana

Si inhabilitaste la compatibilidad con el modo multiventana configurando android:resizeableActivity="false", debes iniciar tu aplicación en un dispositivo con Android 7.0 o una versión posterior, e intentar colocar la aplicación en los modos de forma libre y pantalla dividida. Cuando lo hagas, verifica que la aplicación continúe en el modo de pantalla completa.

Para obtener más información sobre la compatibilidad multiventana en Android, consulta Cinco sugerencias para brindar compatibilidad multiventana en Android N y la aplicación de ejemplo Multi-Window Playground.