Dymki ułatwiają użytkownikom wyświetlanie rozmów i uczestniczenie w nich.
Dymki są wbudowane w system powiadomień. Pływają nad innymi treściami w aplikacji i podążają za użytkownikiem w dowolnym miejscu. Użytkownicy mogą rozwijać dymki, aby odkrywać zawartość aplikacji, i wchodzić z nią w interakcję, a gdy nie są używane, można je zwinąć.
Gdy urządzenie jest zablokowane lub zawsze aktywny wyświetlacz jest włączony, bąbelki pojawiają się tak jak zwykłe powiadomienia.
Bańki są funkcją, 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:
- Blokuj wszystkie dymki z aplikacji. Powiadomienia nie są blokowane, ale nigdy nie pojawiają się jako dymki.
- 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ść tak, aby wyświetlała się prawidłowo jako dymek. 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.
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 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
na "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:
- Utwórz powiadomienie w zwykły sposób.
- Aby utworzyć obiekt
BubbleMetadata
, wywołaj funkcjęBubbleMetadata.Builder(PendingIntent, Icon)
lubBubbleMetadata.Builder(String)
. - Użyj
setBubbleMetadata()
, aby dodać metadane do powiadomienia. - 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.
- Zmień aplikację tak, aby nie blokowała powiadomień wyświetlanych jako dymki.
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 w chwili wysyłania dymku aplikacja działa na pierwszym planie, ważność jest ignorowana, a dymek zawsze się wyświetla, 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.
Oto metody ustawiania flag, które umożliwiają takie 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ę dymki
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 w postaci bąbelka pojawi się tylko wtedy, gdy spełniony jest co najmniej 1 z tych warunków:
- Powiadomienie używa
MessagingStyle
i ma dodanyPerson
. - Powiadomienie pochodzi z połączenia do
Service.startForeground
, zawieracategory
zCATEGORY_CALL
i dodanoPerson
. - W chwili wysyłania powiadomienia aplikacja działa na pierwszym planie.
Jeśli żaden z tych warunków nie jest spełniony, zamiast okienka wyświetla się powiadomienie.
Uruchamianie działań z dymków
Gdy okno z bąbelkiem uruchomi nową aktywność, nowa aktywność zostanie uruchomiona w ramach tego samego zadania i tego samego okna z bąbelkiem albo w ramach nowego zadania na pełnym ekranie, a okno z bąbelkiem, które uruchomiło nową aktywność, zostanie zwinięte.
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 jego obrębie 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 powiadomienia w postaci bąbelków tylko wtedy, gdy są ważne, np. gdy są częścią bieżącej komunikacji lub gdy użytkownik wyraźnie poprosi o wyświetlenie bąbelka dla danej 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 bańkę, powiadomienie w bańce będzie wyświetlane jako zwykłe powiadomienie.
- Wywołanie
super.onBackPressed
, gdy zastępujeszonBackPressed
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ę w nim ikona plakietki wskazującej nieprzeczytaną wiadomość. Gdy użytkownik otworzy wiadomość w powiązanej aplikacji, wykonaj te czynności:
- Zaktualizuj
BubbleMetadata
, aby wyłączyć powiadomienie. Zadzwoń pod numerBubbleMetadata.Builder.setSuppressNotification()
. Spowoduje to usunięcie plakietki, która informuje, że użytkownik wszedł w interakcję z wiadomością. - Ustaw
Notification.Builder.setOnlyAlertOnce()
natrue
, aby wyciszyć dźwięki lub wibracje towarzyszące aktualizacjiBubbleMetadata
.
Przykładowa aplikacja
Przykładowa aplikacja Osoby to aplikacja do rozmów, która korzysta z bańek. Do celów demonstracyjnych aplikacja używa czatbotów. W przypadku rzeczywistych aplikacji używaj bąbelków do wyświetlania wiadomości od ludzi.