How to implement stacked notifications - android

I'm looking at this code in the Android documentation for stacking notifications:
mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = 1;
mNotifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
numMessages = 0;
// Start of a loop that processes data and then notifies the user
...
mNotifyBuilder.setContentText(currentText)
.setNumber(++numMessages);
// Because the ID remains unchanged, the existing notification is
// updated.
mNotificationManager.notify(
notifyID,
mNotifyBuilder.build());
...
but I don't understand how you can keep track of the numMessages parameter across multiple receipts from GCM or how you can start a "loop that processes data" as they say in comments. I would think you would need to retrieve any current notifications and then append the new data to them. Any help appreciated.
edit: I also don't understand what the point of iterating over the loop would be if each notification overwrites the last one, why not just send a notification for the last iteration of this loop?

Try it:
new Notification.Builder().setAutoCancel(false).setOngoing(false);
Good luke!

mBuilder.setAutoCancel(true);//automatically canceled when the user clicks it
mBuilder.setOngoing(true);/*if true:
Ongoing notifications differ from regular notifications in the following ways:
Ongoing notifications are sorted above the regular notifications in the notification panel.
Ongoing notifications do not have an 'X' close button, and are not affected by the "Clear all" button. */

Related

Android update app badge count without push notification Android Oreo+

I want to update app icon badge count without push notifications(eg. Silent push). I simply want to update app badge count after reading any notifications inside the app similar to linkedIn, where its updating the count on app badge when am reading any notification. Currently I've implemented the solution where I am having payload from FCM with badge count and updating it with android notification builder with silent push notification channel configured.
var notificationBuilder = NotificationCompat.Builder(this#MainActivity, CHANNEL_ID)
.setContentTitle("New Messages")
.setContentText("You've received 3 new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setNumber(messageCount)
.build()
but that is not gonna work for me as I also need to update the count once I've read any notification inside the app. If I clear the notification from notification tray then count is also disappearing from app badge, is there any way that I can set that count without push notification within the app? Thanks in advance.
So after working around badge count update feature so long, I've come to conclusion that Android do not provide any api to update badge count on app icon without notification. In android we can internally send notification and with the help of this we can update badge count.
So we need to notify the device for updating badge count, without notifying we can't update it. If we are sending count to Notification Builder then we just need to take care to update badge count to keep the notification id same every time if we want to update the badge count otherwise it will add count to its previous notification. Just keep notification id same and create a separate channel with silent push to update badge count.
public static int NOTIFICATION_ID = 1001;
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
that solution will override previous count.

Stacking notifications from GCM is not working with setGroup

I have the following notification logic inside a class that extends GcmListenerService, and gets called when one notification arrives. Then, when clicked, the app takes you to MainActivity where the notification is displayed properly.
public static void mostrarAvisoBarraEstado(Context context, String alerts)
{
Intent notificationIntent = new Intent(context.getApplicationContext(), MainActivity.class);
notificationIntent.putExtra("alerts", alerts);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, new Random().nextInt(),
notificationIntent, 0);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(context)
.setContentTitle(context.getString(R.string.app_name))
.setContentText("Alert received")
.setSmallIcon(R.drawable.nubeazul)
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.setGroup(GRUPO_ALERTAS)
.setGroupSummary(true)
.setAutoCancel(true)
.build();
//notificationManager.notify(0, notification);
notificationManager.notify (new Random().nextInt(), notification);
}
So, right now, each one is displayed separately, and if they build up, the result is rather ugly with all the notification bar full of little icons. Can you guys help for an elegant solution since I am kindda new to Android? Thanks a lot!
NEW STUFF ADDED today!
If I take the notify random out, leaving something like notificationManager.notify(0, notification);, I will get just one notification, but nothing else, then when it launches MainActivity (its onResume() method) it will only display one notification and all the "piled up ones" are just discarded when clicked on the one notification. What I want to achieve is that while maintaining a clean display, i.e: one group notification for all GCM, if I click on the group, I will get each and every notification displayed throught the Alerts.class (something like looping through the notifications, and starting the activity Alerts for each one.
#Override
protected void onResume()
{
super.onResume();
if (getIntent().hasExtra("alerts"))
{
Bundle extras = getIntent().getExtras();
Intent intent = new Intent(this, Alerts.class);
intent.putExtra("alerts" , extras.getString("alerts"));
startActivity(intent);
getIntent().removeExtra("alerts");
}
}
Then the Alerts class will nicely display the alert which it does, but one per notification.
So I tried out your code and managed to see reproduce what you were encountering (I just manually created dummy notifications). So the reason that the Notifications were piling up was because the id you are passing in the notificationManager.notify() is different from one another. As to what I have observed on the Notification and NotificationManagers behavior so far, the id indicated in notify() it kinda represents the id location/position (not sure what to call it) of the Notification that is under the NotificationManager, not an id of the Notification itself.
Imagine the NotificationManager as an array or list. If for example, you have 3 visible notifications on the Status Bar:
Notification 1, Notification 2, Notification 3 and their ids are as follows: 0, 1, 2.
If you generate a new Notification 4 then called notify passing it as a parameter, and the id 1, the notifications that will be currently shown in the NotificationManager would result to something like this:
Notification 1, Notification 4, Notification 3 and their ids are as follows: 0, 1, 2.
So the reason that you're notifications are piling up and NOT grouping together is because you end up with different ids when calling notify() while passing new Random().nextInt().
As per the behavior that I think you are aiming for -- Joining the notifications from your app into one -- the implementation is simple when understood, but I think it's still a little bit tricky. It's like you have to check first if there is more than 1 notification already, then if yes, you create a summary notification with the details and you show it alone (mind the id ;)) and all of those other stuff. I found this blog though that I think might help you with it. Or you can simply just check out the official docs on Stacking Notifications.
So bottom line, simply use a single id to pass in notify() when it comes to your apps Notifications. Hope this helps. Cheers! :D

Updating an android notification sequentially

I am building a messaging application that notifies users when a new message comes in.
Because this could happen several times a day (or several times an hour), I don't want to continually throw new notifications. Instead, if the user has not dismissed a notification, I would like to update it with the number of new messages pending (following the "Stacking" design guideline).
In the Android documentation, there is an example of updating a notification with a number:
mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = 1;
mNotifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
numMessages = 0;
// Start of a loop that processes data and then notifies the user
...
mNotifyBuilder.setContentText(currentText)
.setNumber(++numMessages);
// Because the ID remains unchanged, the existing notification is
// updated.
mNotificationManager.notify(
notifyID,
mNotifyBuilder.build());
...
HOWEVER, this seems to assume that you are maintaining this number within your application and outside of the notification manager / builder. For a host of reasons, this is very inconvenient (and brittle) in the context of my application.
I would like to know - is there any way to read the current number assigned to a message (the equivalent of mNotifyBuilder.getNumber()) ?
FOLLOW-ON QUESTION: If reading the current number is not possible, is there a way to know from a running service if a notification has been cancelled or manually dismissed by the user ?
You notification is assigned with an ID. You can use this ID to cancel or update the same notification if it hasn't been cancelled by the user.
Straight from the documentation: "If a notification with the same id
has already been posted by your application and has not yet been
canceled, it will be replaced by the updated information."
See this post and that one.

Managing notifications

I'm developing a messaging app that potentially creates multiple notifications. I want it such that these notifications can be updated and deleted when stuff happens.
For example, if I receive a message from A, the notification should say "You have 1 message from A". If another message arrives, it should say "You have 2 messages from A".
Then, if I receive a message from B, it should be a consolidated notification that simply says "You have messages" rather than a separate notification from each sender.
Also, when I click on the notification, it should cancel, and if I click on the user A chat window, any notification from user A should also cancel.
Right now I've implemented the code below for generating notifications:
PendingIntent pendingIntent = PendingIntent.getActivity(context, -1, launchIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder noti = new NotificationCompat.Builder(
context).setContentTitle(context.getResources().getString(R.string.app_name))
.setContentText(notificationMessage)
.setSmallIcon(R.drawable.ic_stat_notify)
setContentIntent(pendingIntent)
setAutoCancel(true)
setWhen(System.currentTimeMillis())
setDefaults(Notification.DEFAULT_ALL);
notificationManager.notify(notifyId, noti.build());
This creates the notification just fine, and cancels it when the user clicks on it. However, I'm unsure how to update notifications, consolidate them, and cancel the appropriate ones. Does anyone know?
Thanks.
You need to use the same Notification ID all the time
public void notify(int id, Notification notification)
id - Post a notification to be shown in the status bar. If a notification with the same id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information.
Just post a new notification with the same ID as the old one, that will replace the old notification with your new one.

Android: How can I put my notification on top of notification area?

I'm trying to put my notification on top of notification area.
A solution is to set the parameter "when" to my notification object with a future time like:
notification.when = System.currentTimeMills()*2;
The code that I'm using in this:
long timeNotification = System.currentTimeMillis()*2;
Notification notification = new Notification(statusIcon,c.getResources().getString(R.string.app_name),timeNotification);
notification.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
notification.when = timeNotification;
notification.priority = Notification.PRIORITY_MAX;
but some apps (like Facebook) are able to put a simple notification with their current time over mine.
If I refresh my notification it remains under these ones.
What parameters I have to set to put my Notification to the top of the notifications area?
You should do this. Other answers seem outdated.
NotificationCompat.Builder mBuilder =
(NotificationCompat.Builder) new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.some_small_icon)
.setContentTitle("Title")
.setContentText("This is a test notification with MAX priority")
.setPriority(Notification.PRIORITY_MAX);
setPriority(Notification.PRIORITY_MAX) is important. It can also be replaced with any of the following as per requirement.
Different Priority Levels Info:
PRIORITY_MAX --
Use for critical and urgent notifications that alert the user to a condition that is time-critical or needs to be resolved before they can continue with a particular task.
PRIORITY_HIGH --
Use primarily for important communication, such as message or chat events with content that is particularly interesting for the user. High-priority notifications trigger the heads-up notification display.
PRIORITY_DEFAULT --
Use for all notifications that don't fall into any of the other priorities described here.
PRIORITY_LOW --
Use for notifications that you want the user to be informed about, but that are less urgent. Low-priority notifications tend to show up at the bottom of the list, which makes them a good choice for things like public or undirected social updates: The user has asked to be notified about them, but these notifications should never take precedence over urgent or direct communication.
PRIORITY_MIN --
Use for contextual or background information such as weather information or contextual location information. Minimum-priority notifications do not appear in the status bar. The user discovers them on expanding the notification shade.
For more details check the following link:
http://developer.android.com/design/patterns/notifications.html#correctly_set_and_manage_notification_priority
You can make your notification Ongoing, when it will appear higher then other usual notification. But in this case user would not be able to clear it manually.
In order to do this set flags to your Notification object:
notif.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR
Try setting priority of the notification to high
documentation > Notification Priority
Also check this question may it could help you Pin Notification to top of notification area
Please note that if you want a "heads-up" notification i.e., one that displays over the top of the current user window you must have the following set in your builder:
setDefaults(NotificationCompat.DEFAULT_VIBRATE)
The reference is in the javadoc:
A notification that vibrates is more likely to be presented as a heads-up notification, on some platforms.
Complete example for a heads-up notification:
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.some_small_icon)
.setContentTitle("Title")
.setContentText("This is a test notification with MAX priority")
.setPriority(Notification.PRIORITY_MAX)
.setDefaults(NotificationCompat.DEFAULT_VIBRATE);

Categories

Resources