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

Dymki ułatwiają użytkownikom przeglądanie 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 zawsze aktywny wyświetlacz jest włączony, bąbelki pojawiają się tak jak zwykłe powiadomienia.

Dymki to funkcja, z której można zrezygnować. 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 bańki

Bańki są tworzone za pomocą interfejsu API powiadomień, więc wysyłaj powiadomienia w zwykły sposób. 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 mieć możliwość zmiany rozmiaru i być osadzone. Jeśli nie spełnia któregoś z tych wymagań, wyświetla się jako powiadomienie.

Ten kod pokazuje, jak zastosować bańkę:

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

Jeśli Twoja aplikacja wyświetla wiele bąbelków tego samego typu, np. wiele rozmów na czacie z różnymi kontaktami, aktywność musi mieć możliwość uruchamiania wielu wystąpień. Na urządzeniach z Androidem 10 lub starszym powiadomienia nie są wyświetlane jako bąbelki, chyba że ustawisz wartość documentLaunchMode jako "always". Począwszy od Androida 11 nie musisz już jawnie ustawiać tej wartości, ponieważ system automatycznie ustawia documentLaunchMode wszystkich rozmów na "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 reklamy na użytkowników korzystających z Androida 11 lub nowszego, upewnij się, że metadane bąbelka lub powiadomienie odwołują się do skrótu udostępniania.
  5. Zmodyfikuj aplikację, aby nie anulowała powiadomienia, które pojawiają się jako bąbelki. Aby sprawdzić, czy aktywność powiadomienia jest uruchamiana jako okno, wywołaj funkcję Activity#isLaunchedFromBubble(). Anulowanie powiadomienia powoduje usunięcie dymka z ekranu. Otwarcie okienka automatycznie spowoduje ukrycie powiązanego z nim powiadomienia.

Te kroki są 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 Twoja aplikacja jest na pierwszym planie, gdy wysyłasz dymek, jego ważność jest ignorowana i dymek jest zawsze wyświetlany, chyba że użytkownik zablokuje dymki lub powiadomienia z aplikacji.

Tworzenie rozwiniętego dymka

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.

Możesz użyć tych metod, aby ustawić flagi umożliwiające te zachowania: setAutoExpandBubble() i 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 w dymku

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 jeszcze nim nie jest).

Gdy okno zostanie zwinięte lub zamknięte, aktywność zostanie zniszczona. Może to spowodować umieszczenie procesu w pamięci podręcznej i późniejsze jego zakończenie, w zależności od tego, czy aplikacja ma inne aktywne komponenty.

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 przeznaczona na Androida 10 lub starszego, powiadomienie wyświetla się jako bańka tylko wtedy, gdy spełniony jest co najmniej 1 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

Gdy bańka uruchamia nową aktywność, nowa aktywność uruchamia się w ramach tego samego zadania i tego samego okienka bańki lub w ramach nowego zadania na pełnym ekranie, a bańka, która ją uruchomiła, zostaje zamknięta.

Aby uruchomić nową aktywność w tym samym zadaniu, co bańka: 1. Używaj kontekstu aktywności podczas uruchamiania intencji, activity.startActivity(intent)i 1. Nie ustawiaj flagi FLAG_ACTIVITY_NEW_TASK w 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 podejmowane w dymku powinny być z nią powiązane. 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 powiadomienie w postaci okienka tylko wtedy, gdy jest ono ważne, np. gdy jest częścią bieżącej komunikacji lub gdy użytkownik wyraźnie poprosi o okienko dla treści. Bańki zajmują miejsce na ekranie i przykrywają inne treści aplikacji.
  • Upewnij się, że powiadomienie w bańce działa też jak zwykłe powiadomienie. Gdy użytkownik wyłączy dymek, powiadomienie w dymku będzie wyświetlane jako zwykłe powiadomienie.
  • Wywołanie super.onBackPressed, gdy zastąpisz 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 SociaLite to aplikacja do rozmów, która korzysta z dymków. W celu demonstracji ta aplikacja korzysta z botów. W przypadku aplikacji rzeczywistych używaj bąbelków do wiadomości od ludzi.