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.
Related
about event for click on notification:
I am searching since yesterday about that , what I found/understood: in FirebaseMessagingService will receive notification data , after will fire local notification, so need to add event in that local notification, I tried to add that many times with many ways but nothing worked …
after I tried to deleted notification files (firebase notification files, and local notification files) but still can receive notification. do you know how to know if the user clicked on the notification ?
To receive messages, use a service that extends FirebaseMessagingService. Your service should override the onMessageReceived and onDeletedMessages callbacks. It should handle any message within 20 seconds of receipt (10 seconds on Android Marshmallow). The time window may be shorter depending on OS delays incurred ahead of calling onMessageReceived. After that time, various OS behaviors such as Android O's background execution limits may interfere with your ability to complete your work.
For further info. you can visit the official website:
Link: https://firebase.google.com/docs/cloud-messaging/android/receive
Hope you'll get your answer here.
Step 1:
// Create an Intent for the activity you want to start
Intent intent = new Intent(this, MainActivity.class);
Step 2:
// Create the PendingIntent
PendingIntent pendingIntent = PendingIntent.getActivity(this, Calendar.getInstance().get(Calendar.MILLISECOND), intent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
Step3:
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setContentIntent(pendingIntent);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(NOTIFICATION_ID, builder.build());
Whenever a user clicks on notification MainActivity will be opened.
Here is details implementation of Android Notification Sample https://github.com/android/user-interface-samples/tree/master/Notifications
I am making an app for my university, now in which I want to send messages/information about events. How I can send info to them. I tried firebase but, it is working till push notification only. I want if someone clicks on the notification it should open a new activity with whole message/info any code reference will be very helpful.
use the payload to put information into your notification. this could be an event id. The text of your notification is is also set by your server.
Thanks to the payload, your app client knows what event ID was received with the notification (when notification was opened). Just ask your database about information from the received event id from the client and you have all you need.
public void getnotification() {
NotificationManager notificationmgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent intent = new Intent(this, your_acitivity.class);
PendingIntent pintent = PendingIntent.getActivities(this, (int) System.currentTimeMillis(), new Intent[]{intent}, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notif = new Notification.Builder(this)
.setSmallIcon(R.drawable.shadow_fiend)
.setContentTitle(notif_title)//Title of the notification
.setContentText(notif_detail)//Description of the notification
.setContentIntent(pintent)
.setAutoCancel(true)
.build();
notificationmgr.notify(0, notif);
}
When the above function is called a notification is generated and by clicking the notification the user is redirected to a specific activity. In the intent replace the your_acitivity.class to whatever activity you want to be redirected when notification is clicked.
Feel free to comment if I misunderstood your requirements.
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
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.
I'm implementing GCM in my app and keeping a hash of notifications to keep track of what is in the notification shade (I have to change intents based on if the user is in or out of app).
I set the deleteIntent PendingIntent for all my notifications. All this does is remove the Notification from my local hash so it won't be updated anymore. The intent is fired fine if I clear all or swipe to delete a notification. However, I also set my notifications to auto cancel. Clicking on a notification does not trigger the deleteIntent for my notification.
My question is, is there any way to be notified when my Notifications are auto-cancelled?
This bug has been reported, but it doesn't look like it has been investigated at all. To work around this here's what I did:
Turn off auto cancel
Use broadcast for both content and delete intents with different actions
Broadcast receiver checks action
Content action: Do both click and delete operations, and cancel notification manually
Delete action: Do delete operation only
For example:
Send Notification
Notification.Builder builder = new Notification.Builder(context)
// Set other properties (not auto-cancel)
.setContentIntent(PendingIntent.getBroadcast(context, 0, new Intent(NOTIFICATION_CLICKED_ACTION), 0))
.setDeleteIntent(PendingIntent.getBroadcast(context, 0, new Intent(NOTIFICATION_DELETED_ACTION), 0));
notificationManager.notify(NOTIFICATION_ID, builder.build());
Receive Broadcast
if (intent.getAction().equals(NOTIFICATION_CLICKED_ACTION)) {
startActivity(new Intent(context, MyActivity.class));
notificationManager.cancel(NOTIFICATION_ID);
}
// Do deletion behaviour here (for both click and delete actions)
This is the correct behaviour od the DeleteIntent as described here in the Android SDK documentation:
Supply a PendingIntent to send when the notification is cleared
explicitly by the user.
The DeleteIntent will only get called when the notification is explicitly cleared by the user by swiping it away or by using the "clear all" function of the notification menu. Tapping on the notification will ONLY trigger the ContentIntent EVEN IF the AutoCancel is set to True.
Documentation says here and here, that clicking on notification with FLAG_AUTO_CANCEL cancels it automatically. This behavior means also that regular contentIntent (if set) will fire along with automatic cancellation, because it is fired in response for user's click action.
Use contentIntent field along with deleteIntent to detect cancellation performed by explicit user tap.