Используйте пузыри, чтобы позволить пользователям участвовать в беседах.

Пузыри облегчают пользователям просмотр бесед и участие в них.

Рисунок 1. Облако чата.

Пузыри встроены в систему уведомлений. Они плавают поверх другого контента приложения и следуют за пользователем, куда бы он ни пошел. Пользователи могут расширять пузырьки, чтобы показывать содержимое приложения и взаимодействовать с ним, а также могут сворачивать их, когда они ими не пользуются.

Когда устройство заблокировано или включен режим «Всегда на дисплее», появляются пузырьки, как обычно в уведомлениях.

Пузыри — это возможность отказа. Когда приложение представляет свой первый пузырь, диалоговое окно разрешений предлагает два варианта:

  • Заблокируйте все пузыри из вашего приложения. Уведомления не блокируются, но они никогда не отображаются в виде пузырьков.
  • Разрешите все пузыри из вашего приложения. Все уведомления, отправленные с помощью BubbleMetaData отображаются в виде пузырьков.

Пузырьковый API

Пузыри создаются с помощью API уведомлений, поэтому отправляйте уведомления как обычно. Если вы хотите, чтобы ваше уведомление отображалось в виде пузырька, прикрепите к нему дополнительные данные.

Развернутое представление пузырька создается на основе выбранного вами действия. Настройте действие для правильного отображения в виде пузырька. Действие должно иметь изменяемый размер и быть встроенным . Если какое-либо из этих требований отсутствует, вместо этого оно отображается в виде уведомления.

Следующий код демонстрирует, как реализовать пузырь:

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

Если в вашем приложении отображается несколько пузырьков одного типа, например несколько разговоров в чате с разными контактами, у действия должна быть возможность запуска нескольких экземпляров. На устройствах под управлением Android 10 и более ранних версий уведомления не отображаются в виде пузырьков, если вы явно не установили для documentLaunchMode значение "always" . Начиная с Android 11, вам не нужно явно задавать это значение, поскольку система автоматически устанавливает documentLaunchMode всех разговоров значение "always" .

Чтобы отправить пузырь, выполните следующие действия:

  1. Создайте уведомление, как обычно.
  2. Вызовите BubbleMetadata.Builder(PendingIntent, Icon) или BubbleMetadata.Builder(String) чтобы создать объект BubbleMetadata .
  3. Используйте setBubbleMetadata() , чтобы добавить метаданные в уведомление.
  4. Если вы ориентируетесь на Android 11 или более позднюю версию, убедитесь, что метаданные пузырька или уведомление ссылаются на ярлык общего доступа.

Эти шаги показаны в следующем примере:

Котлин

// 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)

Ява

// 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);

Если ваше приложение находится на переднем плане при отправке пузырька, важность игнорируется, и ваш пузырь всегда отображается, если только пользователь не заблокирует всплывающие окна или уведомления из вашего приложения.

Создайте расширенный пузырь

Вы можете настроить свой пузырь так, чтобы он автоматически отображался в развернутом состоянии. Мы рекомендуем использовать эту функцию только в том случае, если пользователь выполняет действие, в результате которого появляется пузырь, например, нажимает кнопку, чтобы начать новый чат. В этом случае также имеет смысл отключить первоначальное уведомление, отправляемое при создании пузырька.

Существуют методы, которые вы можете использовать для установки флагов, которые включают такое поведение: setAutoExpandBubble() и setSuppressNotification() .

В следующем примере показано, как настроить всплывающее окно для автоматического отображения в развернутом состоянии:

Котлин

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

Ява

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

Жизненный цикл пузырькового контента

Когда пузырь расширяется, активность содержимого проходит обычный жизненный цикл процесса , в результате чего приложение становится приоритетным процессом, если это еще не произошло.

Когда пузырь схлопывается или закрывается, деятельность уничтожается. Это может привести к кэшированию процесса, а затем его завершению, в зависимости от того, работают ли в приложении другие компоненты переднего плана.

Когда появляются пузырьки

Чтобы уменьшить количество отвлекающих факторов для пользователя, пузырьки появляются только при определенных обстоятельствах.

Если приложение предназначено для Android 11 или более поздней версии, уведомление не отображается в виде пузырька, если оно не соответствует требованиям разговора . Если приложение предназначено для Android 10 или более ранней версии, уведомление отображается в виде пузырька только в том случае, если выполнено одно или несколько из следующих условий:

  • В уведомлении используется MessagingStyle и добавлено Person .
  • Уведомление происходит от вызова Service.startForeground , имеет category CATEGORY_CALL и добавлено Person .
  • Приложение находится на переднем плане при отправке уведомления.

Если ни одно из этих условий не выполнено, вместо пузырька отображается уведомление.

Запуск активности из пузырей

Когда пузырь запускает новое действие, новое действие запускается либо в той же задаче и в том же всплывающем окне, либо в новой задаче в полноэкранном режиме, сворачивая пузырь, который его запустил.

Чтобы запустить новое действие в той же задаче, что и пузырь: 1. Используйте контекст действия при запуске намерений, activity.startActivity(intent) и 1. Не устанавливайте флаг FLAG_ACTIVITY_NEW_TASK для намерения.

В противном случае новое действие запускается в новой задаче, и пузырь схлопывается.

Помните, что пузырь представляет собой конкретный разговор, поэтому действия, запускаемые в нем, должны быть связаны с этим разговором. Кроме того, запуск действия внутри пузырька увеличивает стек задач пузырька и потенциально может усложнить взаимодействие с пользователем, особенно в области навигации.

Лучшие практики

  • Отправляйте уведомление в виде всплывающего окна только в том случае, если оно важно, например, когда оно является частью текущего общения или если пользователь явно запрашивает всплывающее окно для содержимого. Пузыри используют пространство экрана и закрывают другой контент приложения.
  • Убедитесь, что всплывающее уведомление работает как обычное уведомление. Когда пользователь отключает всплывающее уведомление, всплывающее уведомление отображается как обычное уведомление.
  • Вызовите super.onBackPressed при переопределении onBackPressed в действии пузырька. В противном случае ваш пузырь может вести себя неправильно.

Когда свернутый пузырь получает обновленное сообщение, в нем отображается значок значка, указывающий на непрочитанное сообщение. Когда пользователь открывает сообщение в связанном приложении, выполните следующие действия:

  • Обновите BubbleMetadata , чтобы подавить уведомление. Вызовите BubbleMetadata.Builder.setSuppressNotification() . При этом значок значка будет удален, указывая на то, что пользователь взаимодействовал с сообщением.
  • Установите Notification.Builder.setOnlyAlertOnce() значение true , чтобы подавить звук или вибрацию, сопровождающие обновление BubbleMetadata .

Пример приложения

Пример приложения «Люди» — это приложение для общения, в котором используются пузырьки. В демонстрационных целях это приложение использует чат-ботов. В реальных приложениях используйте пузырьки для сообщений от людей.