Usa burbujas para permitir que los usuarios participen en conversaciones

Las burbujas permiten que los usuarios vean las conversaciones y participen en ellas con mayor facilidad.

Figura 1: Una burbuja de chat.

Las burbujas están integradas en el sistema de notificaciones. Flotan sobre el contenido de otra app y siguen al usuario a donde quiera que vaya. Los usuarios pueden expandir las burbujas para revelar información y funciones de la app, y pueden contraerlas cuando no las usen.

Cuando el dispositivo está bloqueado o la pantalla siempre activa está activa, las burbujas aparecen como lo hacen normalmente las notificaciones.

Las burbujas se pueden inhabilitar. Cuando una app muestra su primera burbuja, un diálogo de permisos ofrece dos opciones:

  • Bloquea todas las burbujas de tu app. Las notificaciones no se bloquean, pero nunca aparecen como burbujas.
  • Permite todas las burbujas de tu app. Todas las notificaciones enviadas con BubbleMetaData aparecen como burbujas.

La API de burbujas

Las burbujas se crean mediante la API de notificaciones, por lo que debes enviar la notificación como siempre. Si quieres que la notificación se muestre como una burbuja, adjunta datos adicionales.

La vista expandida de una burbuja se crea a partir de una actividad que elijas. Configura la actividad para que se muestre correctamente como una burbuja. Se debe poder cambiar de tamaño y se debe incorporar. Si falta alguno de estos requisitos, se mostrará como una notificación.

En el siguiente código, se demuestra cómo implementar una burbuja sencilla:

<activity
  android:name=".bubbles.BubbleActivity"
  android:theme="@style/AppTheme.NoActionBar"
  android:label="@string/title_activity_bubble"
  android:allowEmbedded="true"
  android:resizeableActivity="true"
/>

Si tu app muestra varias burbujas del mismo tipo, como varias conversaciones de chat con diferentes contactos, la actividad debe poder iniciar varias instancias. En dispositivos que ejecutan Android 10 y versiones anteriores, las notificaciones no se muestran como burbujas, a menos que configures documentLaunchMode explícitamente como "always". A partir de Android 11, no necesitas configurar este valor de forma explícita, ya que el sistema establece automáticamente el documentLaunchMode de todas las conversaciones en "always".

Para enviar una burbuja, sigue estos pasos:

  1. Crea una notificación como lo haces normalmente.
  2. Llama a BubbleMetadata.Builder(PendingIntent, Icon) o BubbleMetadata.Builder(String) para crear un objeto BubbleMetadata.
  3. Usa setBubbleMetadata() para agregar los metadatos a la notificación.
  4. Si orientas tu app a Android 11 o versiones posteriores, asegúrate de que los metadatos del cuadro o la notificación hagan referencia a un acceso directo de uso compartido.

Estos pasos se muestran en el siguiente ejemplo:

Kotlin

// Create a bubble intent.
val target = Intent(context, BubbleActivity::class.java)
val bubbleIntent = PendingIntent.getActivity(context, 0, target, 0 /* flags */)
val category = "com.example.category.IMG_SHARE_TARGET"

val chatPartner = Person.Builder()
    .setName("Chat partner")
    .setImportant(true)
    .build()

// Create a sharing shortcut.
val shortcutId = generateShortcutId()
val shortcut =
   ShortcutInfo.Builder(mContext, shortcutId)
       .setCategories(setOf(category))
       .setIntent(Intent(Intent.ACTION_DEFAULT))
       .setLongLived(true)
       .setShortLabel(chatPartner.name)
       .build()

// Create a bubble metadata.
val bubbleData = Notification.BubbleMetadata.Builder(bubbleIntent,
            Icon.createWithResource(context, R.drawable.icon))
    .setDesiredHeight(600)
    .build()

// Create a notification, referencing the sharing shortcut.
val builder = Notification.Builder(context, CHANNEL_ID)
    .setContentIntent(contentIntent)
    .setSmallIcon(smallIcon)
    .setBubbleMetadata(bubbleData)
    .setShortcutId(shortcutId)
    .addPerson(chatPartner)

Java

// Create a bubble intent.
Intent target = new Intent(mContext, BubbleActivity.class);
PendingIntent bubbleIntent =
    PendingIntent.getActivity(mContext, 0, target, 0 /* flags */);

private val CATEGORY_TEXT_SHARE_TARGET =
    "com.example.category.IMG_SHARE_TARGET"

Person chatPartner = new Person.Builder()
        .setName("Chat partner")
        .setImportant(true)
        .build();

// Create a sharing shortcut.
private String shortcutId = generateShortcutId();
ShortcutInfo shortcut =
   new ShortcutInfo.Builder(mContext, shortcutId)
       .setCategories(Collections.singleton(CATEGORY_TEXT_SHARE_TARGET))
       .setIntent(Intent(Intent.ACTION_DEFAULT))
       .setLongLived(true)
       .setShortLabel(chatPartner.getName())
       .build();

// Create a bubble metadata.
Notification.BubbleMetadata bubbleData =
    new Notification.BubbleMetadata.Builder(bubbleIntent,
            Icon.createWithResource(context, R.drawable.icon))
        .setDesiredHeight(600)
        .build();

// Create a notification, referencing the sharing shortcut.
Notification.Builder builder =
    new Notification.Builder(mContext, CHANNEL_ID)
        .setContentIntent(contentIntent)
        .setSmallIcon(smallIcon)
        .setBubbleMetadata(bubbleData)
        .setShortcutId(shortcutId)
        .addPerson(chatPartner);

Si la app está en primer plano cuando se envía una burbuja, la importancia se ignorará y la burbuja se mostrará siempre, a menos que el usuario bloquee las burbujas o las notificaciones de la app.

Cómo crear una burbuja expandida

Puedes configurar tu burbuja para presentarla en estado expandido automáticamente. Te recomendamos que solo uses esta funcionalidad si el usuario realiza una acción que genere una burbuja, como presionar un botón para iniciar un nuevo chat. En este caso, también tiene sentido suprimir la notificación inicial que se envía cuando se crea una burbuja.

Hay métodos que puedes usar para configurar marcas que habiliten estos comportamientos: setAutoExpandBubble() y setSuppressNotification().

En el siguiente ejemplo, se muestra cómo configurar una burbuja para que se presente automáticamente en un estado expandido:

Kotlin

val bubbleMetadata = Notification.BubbleMetadata.Builder()
    .setDesiredHeight(600)
    .setIntent(bubbleIntent)
    .setAutoExpandBubble(true)
    .setSuppressNotification(true)
    .build()

Java

Notification.BubbleMetadata bubbleData =
    new Notification.BubbleMetadata.Builder()
        .setDesiredHeight(600)
        .setIntent(bubbleIntent)
        .setAutoExpandBubble(true)
        .setSuppressNotification(true)
        .build();

Ciclo de vida del contenido del cuadro

Cuando se expande un cuadro, la actividad del contenido pasa por el ciclo de vida del proceso normal, lo que hace que la aplicación se convierta en un proceso en primer plano, si aún no lo está.

Cuando el cuadro se contrae o se descarta, se destruye la actividad. Esto puede provocar que el proceso se almacene en caché y, luego, se finalice, dependiendo de si la app tiene otros componentes en primer plano en ejecución.

Cuándo aparecen las burbujas

A fin de reducir las interrupciones para el usuario, las burbujas solo aparecen en determinadas circunstancias.

Si una app está orientada a Android 11 o versiones posteriores, la notificación no aparecerá como una burbuja, a menos que cumpla con los requisitos de la conversación. Si una app se orienta a Android 10 o versiones anteriores, la notificación aparecerá en forma de burbuja solo si se cumplen una o más de las siguientes condiciones:

Si no se cumple ninguna de estas condiciones, se muestra la notificación en lugar de una burbuja.

Prácticas recomendadas

  • Envía una notificación en forma de burbuja solo si es importante, por ejemplo, si es parte de una comunicación en curso o si el usuario solicita explícitamente una burbuja de contenido. Las burbujas ocupan espacio de la pantalla y cubren el contenido de otras apps.
  • Asegúrate de que la notificación de burbuja también funcione como una notificación normal. Cuando el usuario inhabilita la burbuja, una notificación de burbuja se muestra como una notificación normal.
  • Mantén la funcionalidad lo más específica y ligera posible. Los procesos que se inician desde una burbuja, como las actividades y los diálogos, aparecen dentro del contenedor de la burbuja. Esto significa que un cuadro puede presentar una pila de tareas. La situación puede complicarse si hay muchas funcionalidades o navegación dentro de la burbuja.
  • Llama a super.onBackPressed cuando anules onBackPressed en la actividad de la burbuja. De lo contrario, es posible que la burbuja no se comporte correctamente.

Cuando una burbuja contraída recibe un mensaje actualizado, se muestra un ícono de insignia para indicar que hay un mensaje no leído. Cuando el usuario abra el mensaje en la app asociada, sigue estos pasos:

App de ejemplo

La app de ejemplo Personas es una app de conversación simple que usa burbujas. A modo de demostración, esta app usa chatbots. En aplicaciones reales, solo las personas deben usar las burbujas para enviar mensajes, no los bots.