I want to emulate Gmail's app behavior regarding notification bar notifications, which complies with the recommended Android pattern: http://developer.android.com/design/patterns/notifications.html
When the app is in background and I get a new e-mail I get a notification in the notification bar like this:
Line 1 : Jane Smith
Line 2 : Hi John, this is a sample message...
That is, a notification that is specific for a single message, and tapping it leads to a screen showing that specific e-mail. If I clear the notification either by swiping it or with "Clear all", then when I get a new message I will get another single message specific notification. But if I don't clear it and I get another e-mail then the notification will turn into a summary notification saying "2 New messages", and tapping it leads to the inbox.
I know how to update a notification, the question is how do I figure out which notifications are still there in the notification bar, if any. The answer is not that simple because the notification will not reflect how many unread messages I have, it must reflect which messages are still not acknowledged by the user either by tapping the notification, or clearing it.
Should I keep track of notifications by keeping a list of notifications that we launched, the ones that were tapped (content intent) and the ones cleared (delete intents)? I don't think that approach is fail safe enough... for example: What happens if notifications get cleared because I boot my phone? Where am I supposed to keep track of notifications still showing? Shared preferences?
How do you usually solve this?
I just had the same issue and I also looked at Gmail for the appropriate behaviour. I first studied the following scenarios:
Assuming a user is actively using the Gmail app (disregard any interaction with the browser version), and then navigates away from it:
In API 18, Android added support to retrieve active notifications using NotificationListenerService, however that's too recent for the app I'm working on (min API 14), not to mention you can't rely on that to get the existing notification information if it has already been dismissed by the user.
So the solution I found was to persist information about the notifications already issued locally, use that information to create either a single notification or a summary, and clear everything when the user opens the app again.
To persist the notification information, I created a simple model similar to the following:
public class NotificationBundle {
private String mText;
// Add any other relevant information about your notification here,
// particularly what you used to create your notification intent
// i.e. an item/message id to highlight, maybe?
public String getText() {
return mText;
}
public void setText(final String text) {
mText = text;
}
}
The idea is to create an instance of those for each notification you issue.
Then you have to have in place a way to persist your list of NotificationBundle
objects. I used SharedPreferences
to do that, but you could use whatever else suits you better (like a DB table). To persist a List<NotificationBundle>
in SharedPreferences
I used Gson
to serialize the array into json, and then saved that as a string. Assuming you can use SharedPreferences
, you can find how to do the serialization in this answer.
With that structure in place, basically what's left for you to do is:
When you have to issue a notification:
NotificationBundle
with the information you want to notify.List<NotificationBundle>
from SharedPreferences
NotificationBundle
(from 1) into your existing List<NotificationBundle>
(from 2) and save it to SharedPreferences
.NotificationManager.notify()
. If you always use the same notification id here, it will create a new notification if none from your app are currently visible, or it will just update it if a previous notification is visible.On your onResume()
method of your main Activity, make sure to dismiss all notifications with NotificationManager.cancelAll()
. Also make sure to remove from your SharedPreferences
your existing List<NotificationBundle>
.
And that should do the trick.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With