Używaj dymków, aby umożliwić użytkownikom uczestniczenie w rozmowach

Dymki ułatwiają użytkownikom wyświetlanie rozmów i uczestniczenie w nich.

Rysunek 1. Dymek czatu.

Dymki są wbudowane w system powiadomień. Bańki te unoszą się nad innymi treściami aplikacji i podążają za użytkownikiem. Użytkownicy mogą je rozwijać, aby wyświetlić i interagować z treściami aplikacji, oraz składać je, gdy ich nie używają.

Gdy urządzenie jest zablokowane lub włączony jest tryb Zawsze na ekranie, dymki wyświetlają się jako tak jak zwykle.

Dymki można wyłączyć. Gdy aplikacja wyświetla pierwszą bańkę, w oknie z prośbą o uprawnienia użytkownik ma do wyboru 2 opcje:

  • Blokowanie wszystkich dymek z aplikacji. Powiadomienia nie są blokowane, ale nigdy nie wyświetlają się jako bąbelki.
  • Zezwalaj na wszystkie dymki z aplikacji. Wszystkie powiadomienia wysyłane za pomocą BubbleMetaData będą wyświetlane jako dymek.

Interfejs API dymku

Dymki są tworzone przy użyciu interfejsu API powiadomień, więc wyślij powiadomienie jako w normie. Jeśli chcesz, aby powiadomienie wyświetlało się jako okienko, dołącz do niego dodatkowe dane.

Rozwinięty widok dymka jest tworzony na podstawie wybranej przez Ciebie aktywności. Skonfiguruj aktywność, aby wyświetlała się prawidłowo jako bańka. Działanie musi być resizeable oraz umieszczony. Jeśli nie, któreś z tych wymagań jest wyświetlane jako powiadomienie.

Poniższy kod ilustruje sposób implementacji dymka:

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

Jeśli w aplikacji wyświetla się kilka dymków tego samego typu, np. wiele dymków czatu rozmów z różnymi kontaktami, aktywność musi umożliwiać wiele instancji. Na urządzeniach z Androidem 10 lub starszym: powiadomienia nie są wyświetlane jako dymki, chyba że wyraźnie ustawisz documentLaunchMode do "always" Począwszy od Androida 11 nie trzeba specjalnie zaznaczać ustaw tę wartość, ponieważ system automatycznie ustawia wszystkie wątki documentLaunchMode do "always".

Aby wysłać dymek:

  1. Utwórz powiadomienie w zwykły sposób.
  2. Aby utworzyć obiekt BubbleMetadata, wywołaj funkcję BubbleMetadata.Builder(PendingIntent, Icon) lub BubbleMetadata.Builder(String).
  3. Użyj setBubbleMetadata(), aby dodać metadane do powiadomienia.
  4. Jeśli kierujesz aplikację na Androida 11 lub nowszego, upewnij się, że dymek metadane lub powiadomienie odnoszą się do skrótu do udostępniania.
  5. Zmień aplikację tak, aby nie anulowała powiadomienia, które pojawiają się jako bąbelki. Aby sprawdzić, czy aktywność dotycząca powiadomień jest uruchamiana w postaci dymka, wybierz połączenie Activity#isLaunchedFromBubble() Anulowanie powiadomienia powoduje usunięcie dymka z ekranu. Otwarcie okienka automatycznie spowoduje ukrycie powiązanego z nim powiadomienia.

Czynności te zostały pokazane w tym przykładzie:

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

Jeśli w chwili wysyłania dymku aplikacja działa na pierwszym planie, ważność jest ignorowana a dymek jest zawsze widoczny, chyba że użytkownik zablokuje dymki lub powiadomienia z aplikacji.

Utwórz rozwinięty dymek

Możesz skonfigurować dymek tak, aby automatycznie wyświetlał się w rozwiniętym stanie. Zalecamy używanie tej funkcji tylko wtedy, gdy użytkownik wykona działanie, które powoduje wyświetlenie bąbelka, np. kliknie przycisk, aby rozpocząć nowy czat. W takim przypadku warto też ukryć początkowe powiadomienie wysyłane po utworzeniu okienka.

Istnieją pewne metody ustawiania flag, które umożliwiają takie zachowania: setAutoExpandBubble() oraz setSuppressNotification()

Ten przykład pokazuje, jak skonfigurować bańkę, aby była automatycznie wyświetlana w rozwiniętym stanie:

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

Cykl życia treści dymków

Gdy bańka jest rozwinięta, aktywność związana z treściami przechodzi przez normalny cykl życia procesu, w wyniku czego aplikacja staje się procesem na pierwszym planie (jeśli nie była nim wcześniej).

Gdy dymek zostanie zwinięty lub zamknięty, aktywność zostaje zniszczona. Może to spowodować zapisywanych w pamięci podręcznej, a następnie zatrzymywanych, w zależności od tego, czy Aplikacja ma uruchomione inne komponenty na pierwszym planie.

Kiedy pojawiają się bąbelki

Aby nie zakłócać pracy użytkownikom, bąbelki są wyświetlane tylko w określonych okolicznościach.

Jeśli aplikacja jest kierowana na Androida 11 lub nowszego, powiadomienie nie będzie wyświetlane jako okienko, chyba że spełnia wymagania dotyczące rozmów. Jeśli aplikacja jest kierowana Android 10 lub starszy, powiadomienie wyświetla się jako dymek tylko wtedy, gdy jest spełniony co najmniej jeden z tych warunków:

Jeśli żaden z tych warunków nie jest spełniony, zamiast okienka wyświetla się powiadomienie.

Uruchamianie działań z dymków

Kiedy dymek uruchomi nową aktywność, zostanie ona uruchomiona w ramach tego samego zadania w tym samym oknie z dymkami lub w nowym zadaniu w trybie pełnoekranowym oraz zwiń dymek, który go uruchomił.

Aby uruchomić nowe działanie w ramach tego samego zadania co dymek: 1. Używaj kontekstu aktywności podczas uruchamiania intencji, activity.startActivity(intent)i 1. Nie ustawiaj flagi FLAG_ACTIVITY_NEW_TASK intencji.

W przeciwnym razie nowa aktywność jest uruchamiana w ramach nowego zadania, a bańka jest zwijana.

Pamiętaj, że dymek reprezentuje konkretną rozmowę, więc działania które powinny być powiązane z tą rozmową. Dodatkowo uruchamianie aktywności w bańce zwiększa stos zadań w bańce i może potencjalnie skomplikować korzystanie z aplikacji, zwłaszcza nawigację.

Sprawdzone metody

  • Wysyłaj powiadomienia w postaci dymków tylko wtedy, gdy są one ważne, np. wtedy, gdy jest jako część trwającej komunikacji lub jeśli użytkownik wyraźnie prosi o wyświetlenie dymka treści. Dymki zajmują miejsce na ekranie i zakrywają inne treści w aplikacji.
  • Upewnij się, że powiadomienia w postaci dymków działają jak zwykłe powiadomienia. Kiedy użytkownik wyłączy dymek, powiadomienie w postaci dymka jest wyświetlane powiadomienia.
  • Wywołanie super.onBackPressed, gdy zastępujesz onBackPressed w aktywności bańki. W przeciwnym razie bańka może nie działać prawidłowo.

Gdy zwinięty dymek otrzyma zaktualizowaną wiadomość, pojawi się na nim ikona odznaki, która wskazuje nieprzeczytaną wiadomość. Gdy użytkownik otworzy wiadomość w powiązanej aplikacji, wykonaj te czynności:

Przykładowa aplikacja

Przykładowa aplikacja Osoby to aplikacja do rozmów, która używa bąbelków. W celu ułatwienia demonstracji ta aplikacja korzysta z botów. W prawdziwych aplikacjach używaj dymków do wyświetlania wiadomości ludzi.