Balões

Os balões permitem que os usuários vejam e participem das conversas com mais facilidade.

Os balões são integrados ao sistema de notificações. Eles flutuam sobre o conteúdo de outros apps e seguem o usuário em qualquer tela que ele abra. Os balões podem ser expandidos para revelar funcionalidades e informações do app e podem ser recolhidos quando não estiverem sendo usados.

Quando o dispositivo estiver bloqueado ou a tela estiver no estado de sempre ativada, os balões serão exibidos da mesma forma que uma notificação seria.

"Balões" é um recurso que pode ser desativado. Quando um app apresenta o primeiro balão, uma caixa de diálogo de permissões é exibida, oferecendo duas opções:

  • Bloquear todos os balões do seu app: as notificações não são bloqueadas, mas nunca aparecerão como balões.
  • Permitir todos os balões do app: todas as notificações enviadas com BubbleMetaData aparecerão como balões.

API Bubble

Os balões são criados por meio da API Notification, e a notificação é enviada normalmente. Se você quiser que sua notificação seja exibida como um balão, precisa anexar alguns dados extras a ela.

A exibição expandida de uma bolha é criada a partir de uma atividade escolhida por você. A atividade precisa estar configurada para ser exibida corretamente como um balão. A atividade precisa ser redimensionável e incorporada. Se algum desses requisitos não for cumprido, ela é exibida como uma notificação.

O código a seguir demonstra como implementar uma bolha simples:

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

Se seu app exibe vários balões do mesmo tipo, como várias conversas por chat com diferentes contatos, a atividade precisa ser capaz de iniciar várias instâncias. Em dispositivos com Android 10, as notificações não são exibidas como balões, a menos que você defina documentLaunchMode explicitamente como "always". A partir do Android 11, não é necessário definir explicitamente esse valor, já que o sistema define de forma automática todas as conversas de documentLaunchMode para "always".

Para enviar uma bolha, siga estas etapas:

Kotlin

// Create 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 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 bubble metadata
val bubbleData = Notification.BubbleMetadata.Builder(bubbleIntent,
            Icon.createWithResource(context, R.drawable.icon))
    .setDesiredHeight(600)
    .build()

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

Java

// Create 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 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 bubble metadata
Notification.BubbleMetadata bubbleData =
    new Notification.BubbleMetadata.Builder(bubbleIntent,
            Icon.createWithResource(context, R.drawable.icon))
        .setDesiredHeight(600)
        .build();

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

Se seu app estiver em primeiro plano quando um balão for enviado, a importância será ignorada, e seu balão será sempre exibido, a menos que o usuário tenha bloqueado balões ou notificações do app.

Como criar um balão expandido

Você pode configurar sua bolha para que ela seja automaticamente exibida no estado expandido. Recomendamos que essa funcionalidade só seja utilizada se o usuário executar uma ação que resulte na exibição de uma bolha, como tocar em um botão para iniciar um novo bate-papo. Nesse caso, também faz sentido suprimir a notificação inicial enviada quando um balão é criado.

Há métodos que podem ser usados para definir sinalizações que ativem esses comportamentos: setAutoExpandBubble() e setSuppressNotification().

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 do conteúdo da bolha

Quando um balão é expandido, a atividade do conteúdo passa pelo ciclo de vida de processo normal, resultando na transformação do app em um processo em primeiro plano, se esse ainda não for o caso.

Quando o balão é recolhido ou dispensado, a atividade é destruída. Isso pode fazer com que o processo seja armazenado em cache e, posteriormente, interrompido se o app tiver outros componentes sendo executados em primeiro plano.

Quando as bolhas aparecem

Para reduzir a quantidade de interrupções do usuário, os balões só aparecem em determinadas circunstâncias.

Se um app for direcionado ao Android 11 ou versões mais recentes, uma notificação não aparecerá como um balão a menos que atenda aos requisitos da conversa. Se um app for direcionado ao Android 10, a notificação aparecerá como um balão somente se uma ou mais das seguintes condições forem atendidas:

Se nenhuma dessas condições for atendida, a notificação será exibida em vez de um balão.

Práticas recomendadas

  • Os balões ocupam espaço na tela e cobrem o conteúdo de outros apps. Só envie uma notificação como um balão se ela for importante o suficiente, por exemplo, no caso de comunicações em andamento ou se o usuário pedir explicitamente a exibição de um balão para determinado conteúdo.
  • O balão pode ser desativado pelo usuário. Nesse caso, uma notificação em balão será exibida como uma notificação normal. Sempre verifique se a notificação em balão também funciona como uma notificação normal.
  • Os processos iniciados em um balão, como atividades e diálogos, aparecem dentro do contêiner de balão. Isso significa que um balão pode ter uma pilha de tarefas. Os processos poderão se complicar se houver muitas opções de funcionalidades ou navegação dentro do balão. Recomendamos que você mantenha a funcionalidade o mais leve e específica possível.
  • Chame super.onBackPressed ao substituir onBackPressed na atividade do balão, caso contrário, seu balão pode não se comportar corretamente.
  • Quando um balão recolhido recebe uma mensagem atualizada, ele exibe um ícone de selo para indicar uma mensagem não lida. Quando o usuário abrir a mensagem no app associado, siga estas etapas:

App de amostra

O app de amostra People é um app de conversa simples que usa balões. Para fins de demonstração, este app usa bots de chat. Nos aplicativos reais, os balões só devem ser usados para mensagens enviadas por humanos, não por bots.