Search code examples
androidnotificationsandroid-notificationsandroid-bubbles

How to implement Android Bubbles notifications on Android 11(Api 30)+


I am trying to implement the Android Bubbles notifications API but it's not working for me, it's displaying as an ordinary notification. I am testing on emulator API 30(Android 11). I got the people-example working on the device, and I am following the Conversation Notifications guidelines.

  • The notification uses MessagingStyle.
  • (Only if the app targets Android 11 or higher) The notification is associated with a valid long-lived dynamic or cached sharing shortcut. The notification can set this association by calling setShortcutId() or setShortcutInfo(). If the app targets Android 10 or lower, the notification doesn't have to be associated with a shortcut, as discussed in the fallback options section.
  • The user hasn't demoted the conversation from the conversation section via notification channel settings, at the time of posting.

Please tell me what did I missed?

Also, I got a few optional questions about the design of Bubbles.

  • At what point of the app should I create the shortcuts and when to update it?
  • How the Person object needs to be cached?

This is what I got so far

    Recipient recipient = ...; // Sender data
    Message message = ...;     // Message data

    Intent intent = new Intent(context, ChatActivity.class);
    intent.putExtra(ChatActivity.CONVERSATION_ID, message.conversationId);

    PendingIntent bubbleIntent =
            PendingIntent.getActivity(context, 0, intent, 0);

    IconCompat icon = loadIcon(recipient);
    Person person = loadPerson(recipient, icon);

    NotificationCompat.MessagingStyle style = getMessagingStyle(person);

    createOrVerifyChannel();

    Notification notification = new NotificationCompat.Builder(context, CHANNEL_ID)
            .setContentTitle(getNewMessagesCount(message) + " new messages with " + person.getName())
            .setCategory(Notification.CATEGORY_MESSAGE)
            .setContentText(message.text)
            .setBubbleMetadata(
                    new NotificationCompat.BubbleMetadata.Builder()
                            .setDesiredHeight(600)
                            .setIntent(bubbleIntent)
                            .setAutoExpandBubble(true)
                            .setSuppressNotification(true)
                            .setIcon(icon)
                            .build()
            )
            .addPerson(person)
            .setSmallIcon(R.mipmap.ic_launcher_round)
            .setWhen(message.date)
            .setStyle(style)
            .setShortcutInfo(
                    new ShortcutInfoCompat.Builder(context, message.conversationId + "")
                            .setActivity(new ComponentName(context, ChatActivity.class))
                            .setCategories(new HashSet<>(Collections.singletonList(Notification.CATEGORY_MESSAGE)))
                            .setIcon(icon)
                            .setPerson(person)
                            .setRank(0)
                            .setShortLabel(person.getName())
                            .setIntent(intent)
                            .build()
            )
            .build();


    NotificationManagerCompat.from(context).notify(message.id + "," + message.type,
            message.id, notification);

Manifest

 <activity
        android:name=".screens.chat.ChatActivity"
        android:allowEmbedded="true"
        android:resizeableActivity="true"
        tools:targetApi="n" />

Gradle

targetSDKVersion 30
implementation 'androidx.appcompat:appcompat:1.3.0-alpha02'

Solution

  • The one thing that I missed was adding .setLongLived(true) for the ShortcutInfoCompat. It solves the problem.

    I learned that it best to manage the ShortcutInfo on the app level since you can have at most 5 at a time, so there is no harm caching those in memory, it includes the Person object as well.

    Also, you should add LocusId for the NotificationCompat, this id is shared among shortcuts, notifications, and views. To add it to the views you need to put in some extra work, as described in ContentCaptureManager