Android 11 Updates: Conversations & Bubbles — part 1of 2
Part 1: Conversation Notifications
My story starts when I was a child. I dreamed of having a dog that would be my friend. By the way, I’m not the only child in the family; I have an elder brother. But because he’s much older, he didn’t have a lot of time to play with me. Still, my parents refused me to buy a dog. I was disappointed, but couldn’t do anything about it at that moment.
This post will guide you through my story in which I talk to my virtual friend via a chat application. This is where I experimented with the new API announced for Android 11.
When you reach the end of this article, you will:
- Know how to build a chat app
- Have learned about Shortcut API
- Have tried new API for Shortcuts
- Test Conversation Notifications API
The code is available in the Google repository, or, if you like, you can go to Google Codelabs to play around with the new API.
You’ll be surprised to know that I’ve grown up but still don’t have a dog :) I still really want one, though. But these are different times: We have technologies, and I’m an Android developer. This all leads me to believe that I can have a virtual friend. So why not create a chat app where I can talk to my virtual friend, my lovely pet :) I can even switch the type of dog I have and its picture every day. I also love trying out new things in Android. I can explore the cool new features Android 11 offers. I can combine my wish to have a dog and play around with the new Conversation Notification and Bubbles API that were recently announced.
OK, let’s start building the app. Here’s how my app will work and what it will look like:
It’s just an ordinary chat messenger. Let’s dive in a bit into the main classes I’ll use in the app. I have a class called Chat, which is self-explanatory:
class Chat(val contact: Contact) {…}
I also have an abstract class, Contact, that defines the main properties and the list of contacts with whom I can chat:
I decided to create a list of contacts because, at some point, I’d love to talk to other similar virtual pets. Maybe I’ll have a small zoo in my app :)
From first glance, everything seems quite nice and to be working correctly. I send a message to my friend, and, after some time, I receive a reply. Unfortunately, to see the message from my friend, the chat screen should be in the foreground, or I can open this screen from time to time to check for new messages.
Not very convenient, right? Again, we have a solution in Android Framework for that, too: a notification.
For example, in our Flo Android app, you can chat anonymously to answer popular health questions. Here’s what it looks like:
When you leave a comment, someone can reply, and you receive a notification. I think it’s quite an important notification because when you leave a comment, it means that the topic or question is important to you. When somebody replies to you, that means someone wants to leave you feedback, which may also be important to you. We plan to add this feature in the future, so stay tuned :)
OK, let’s get back to our app and start creating notifications. First, let’s create a notification channel:
I’ll place this code in another helper class and call it NotificationHelper. Please note that I created a channel with IMPORTANCE_HIGH, which will be required later. Let’s do some prep work:
I created a contentUri that will help me create a chat fragment with my friend and a person that will be used later in the Android system. OK, now we’re ready to create a notification:
Yeah, this is my first try. Doesn’t look as fancy as it should, right? Fortunately, Android 11 brings a new section called Conversation Notifications. They’re intended to improve the user experience of real-time conversations. For example, SMS, text chats, and phone calls are real-time conversations where users expect to communicate quickly. Users don’t have that expectation with e-mails and activities unrelated to conversations. This priority is based on the fact that communication and interaction with other people is still the most valued and important functional area for most of our users across all demographics (1).
We’ve given users the ability to remove a given conversation from the conversation section if they don’t feel it’s in the right space. I want to stop here and go through this feature step-by-step to show all the main differences it brings.
I want to play around with this new feature in Android 11. How can we add it? There are two main rules that are important to add to discover that feature:
1. We have to apply the messaging style to our notification. It’s very easy to add:
Basically, this styling was added in Android a long time ago, and it really brings a better look to your notification:
The code is quite simple. It adds an icon for the notification to my virtual friend and adds the ability to display messages in my chat.
As we can see, add a conversation section for my app isn’t enough because:
In Android 11, notifications that refer to valid long-lived conversation shortcuts and use MessagingStyle appear above other notifications.
2. So we have to add a valid long-lived conversation shortcut. Wow, that sure is interesting. But before moving forward, let’s review what a shortcut is:
Shortcuts are a great way to engage users and provide some app menu options even before users launch it.
OK, we don’t have a choice. We need to add a valid shortcut. First, let’s add the id that will be used to create a shortcut. We’ll expand our contact class with this information:
abstract class Contact(...) { ... val shortcutId = "contact_$id"}
Now we’re ready to add shortcuts. We can create a new function called updateShortcuts. As usual, everything starts with the Builder pattern, which, I believe, is the most widespread pattern in the Android framework:
I want to focus on some of the settings that I applied:
.setActivity(ComponentName(context, MainActivity::class.java)).setShortLabel(contact.name).setIcon(icon)
These are pretty standard settings for a shortcut that will add a label and icon to the shortcut.
Next, we want to open the chat screen by tapping on the shortcut. That’s why I put it here.
Then I want to specify a person object that’s necessary to set in the notification, shortcuts, and other places where it’s possible to help Android improve…
Another very important attribute is:
.setLongLived(true)
I spent quite a while wrapping my head around how it’s used and why we need it. I even asked Dan about it on Twitter while preparing this material. In brief, when a shortcut is set to be long-lived, it means that system services can access it from the cache even after it has been removed as a dynamic shortcut. Android 11 was recently released, so we can take a look at the source code later on to see how it’s used across the framework. Another important attribute is:
.setLocusId(LocusId(chat.contact.shortcutId))
which helps the device’s intelligence services to correlate this notification with the corresponding dynamic shortcut. Doing so helps the system to accurately rank conversations based on app usage. Just like any other id, this should be unique. That’s why we can use shortcut id and pass it for the Parcelable Android class LocusId. To make the whole integration notification + shortcut aware of the locus id, we should set it on notification as well:
And on the chat screen:
OK, now we’re almost done setting up all the necessary details to display the conversation notification in the notification manager. We just need to add a shortcut and link it to the notification. Let’s do it:
var shortcuts = ...shortcutManager.addDynamicShortcuts(shortcuts)
In my case, everything works fine, but this is where the catch may be. The system supports a different number of shortcuts, and if I add more than expected, the app will crash with the exception IllegalArgumentException. Developers who have faced this situation tend to add additional logic before adding shortcuts:
To simplify this process, Google added a new API that takes this detail into account and checks maxCount under the hood:
shortcuts.forEach { shortcut -> shortcutManager.pushDynamicShortcut(shortcut)}
So now we’re good to go. We’ve built the shortcut, so let’s link it to the notification:
Basically, we managed to ask Android OS to display our notification as a conversation notification:
If we run the same code on Android 10, we’ll notice small differences with Android 11 when the notification is displayed:
Let’s summarize what we have so far:
Looking at the Android 11 features, we can say that the main priorities were people, communication, and interaction with other people. Nowadays, you do a lot of things on your phone, laptop, or PC. Your gadgets have become one of the main tools of communication. As such, being informed and seeing the most important information was one of the Android Team’s areas of focus. Communication and interaction were the most-valued, important functional areas for most Android users based on feedback the team collected during its preparation. That’s why conversation notifications were introduced, and I hope it will help people pay attention only to important things. In the next article, we’ll cover the Bubbles API and why it’s also a very important update focused on people and communication.
***
At Flo Health, we pay a great deal of attention to communication by creating anonymous chats on different topics. If you want to play around with new features in Android, you can join our team to integrate them into our super app.