12

I have a Notification which is refreshed (i.e. sent) every three seconds. I've set the FLAG_ONGOING_EVENT flag and the FLAG_NO_CLEAR flag so that is always shown. The problem is, that if e.g. a download is active (which displays a progress bar in the notification area) both notifications constantly switch positions as they are both refreshed every few seconds.

How can I pin my notification to the top of the list (or to some static position), so that it stops jumping around every time I update it by calling NotificationManager.notify()?

Edit: Here's the code to update the notification. It's run every three seconds.

Notification notification = new Notification();
notification.contentView = appBarNotification; // this sets the changed notification content
notification.flags |= Notification.FLAG_ONGOING_EVENT;  
notification.flags |= Notification.FLAG_NO_CLEAR; 

Intent notificationIntent = new Intent();
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;
notification.icon = R.drawable.icon;

nm.notify(APP_BAR_NOTIFICATION, notification);
ubuntudroid
  • 3,680
  • 6
  • 36
  • 60

8 Answers8

20

There is a solution that does exactly what you want.

In the Notification class, there is a public field called when. According to the API:

The timestamp for the notification. The icons and expanded views are sorted by this key.

The default behaviour (for code and coders alike :) is to give when the timestamp of the notification:

notification.when = System.currentTimeMillis();

So - in order to maintain the correct order of notifications, all you need to do is give it a preset timestamp instead:

notification.when = previousTimestamp;

When you do this with all of your notifications, they maintain their order. I had the same problem as you and solved it this way.

Vaiden
  • 15,728
  • 7
  • 61
  • 91
  • Hmm, so you're creating a new notification about an event that happened in the past, over and over again. That's clever. I think the single ongoing event notification would be a better solution for most other cases though. – Ed Burnette Jan 05 '12 at 20:55
  • mmmm is the type Long ... you can cast to int, but in versions > 5.0 always on, 2012 works, but in 2015 not work !! sorry deprecated –  Oct 29 '15 at 10:06
  • I was very glad to find a solution to the exact problem I have. But... unfortunately I couldn't understand so simple answer :( . I just couldn't get the point... **previousTimestamp** - where is taken from? Is it time stamp given to the previous notification updated, or is it previous update time of the same notification or what is it? Could anybody clarify, please ? – Liphtier Dec 13 '16 at 15:06
  • @Liphtier - The timestamp of the original notification. As long as you use the same timestamp, the notification would retain its place in the queue. – Vaiden Dec 14 '16 at 12:26
  • @Vaiden - I tried this without success, and it seems like solution is outdated. At least with API >=21, notification **when** value defaults to start time, so setting it manually to the same doesn't have any effect. It doesn't affect the notification order. However, I found that setting high priority - that is the thing that made notifications play leapfrog, they have overriden each one's priority – Liphtier Dec 21 '16 at 13:50
5

You shouldn't keep sending the notification. Just use the ongoing event flag, like you already have in your code. Other notifications may come in and obscure yours, but that's just the way Android works.

Ed Burnette
  • 1,198
  • 8
  • 13
  • I have to resend the notification every few seconds as it is a list of currently running apps which have to be updated. I just want the list at a fixed position (which doesn't have to be necessarily the topmost) so that the user doesn't have to search for it every time he wants to use it. – ubuntudroid Jun 10 '11 at 13:08
  • Hm, it really seems there is no way in Android to achieve the desired behavior. So this answer seems to be the most appropriate one. – ubuntudroid Dec 19 '11 at 11:46
  • Actually there is a solution, at least one that works for me. Please review my answer at the bottom of this page. – Vaiden Jan 05 '12 at 14:03
3

Are you sending a new notification each time, or updating an existing one? Can you post the code?

In the meantime, you can generally answer questions like "Can I pin my notification to a static position, or to the top of the list" by thinking "Wait, what would happen if two or more programs both tried to pin their notification to be first?" and realising that the arms-race that would ensue amongst programs as they try ever harder to make sure their notification is first is why this sort of feature is not supported.

Nik
  • 2,380
  • 2
  • 16
  • 15
  • Nik is correct - if every developer could have _their_ app display notifications above everyone else's, why wouldn't they? – Snailer Jun 01 '11 at 01:01
  • A static position would be enough, it doesn't have to be at the very top of the list - just as high as possible. – ubuntudroid Jun 01 '11 at 09:26
  • I don't know how to "update" an existing notification without resending it with the same ID, so that's basically what I do every three seconds... I'll post the code in the question. – ubuntudroid Jun 01 '11 at 09:28
  • But if you are willing to not be the first, but just have a static position, a sollution that would not "steal first spot" would be viable (and an answer to the question). So the answer to the "what would happen if" would be: they'd get a random (but static) spot in the list. – Nanne Jun 14 '11 at 18:19
  • Yeah, a static position would be completely sufficient. – ubuntudroid Jun 15 '11 at 09:26
  • This would be my answer of choice. As also an avid Android user, I wouldn't want an app to steal the notification for itself, on the first or whatever position. I would rethink your app logic, because if I want to know which apps are open or any other functionality provided by the app, I would open that app. You can create an icon on the not. bar, just like many do (Skype etc.). You don't need to bother the user with one notification every 3 seconds. It's annoying. Good luck! – davidcesarino Jun 15 '11 at 14:17
1

By adding setSortKey(String sortKey) to your notification builder you can have your notifications stay in a constant lexicographical/alphabetical ordering.

lasec0203
  • 2,422
  • 1
  • 21
  • 36
Brandon Bahret
  • 163
  • 3
  • 10
1

It's been some time since I've done code for Android, but if I remember correctly, whenever you call NotificationManager.notify(), it's because you want to alert the user by having an icon move or flash. However, there are ways of modifying the actual notifications you're sending.

You can also call .cancel() on it if that helps.

Here's the Android API documentation for help, although you've probably already seen them:

Notification

NotificationManager

Hope that helped!

Andrei Sfat
  • 8,440
  • 5
  • 49
  • 69
Jonathan Pitre
  • 2,355
  • 3
  • 22
  • 38
  • Sorry, but I didn't find anything about actually "updating" a running notification. Resending (i.e. calling notify()) with the new content is the only way I'm aware of... – ubuntudroid May 31 '11 at 16:01
1

There is an Ongoing Event Flag. http://developer.android.com/reference/android/app/Notification.html#FLAG_ONGOING_EVENT

You don't need the Notification.FLAG_NO_CLEAR flag.

David Shellabarger
  • 1,523
  • 2
  • 15
  • 23
  • As you can see I already use the FLAG_ONGOING_EVENT in my code. The problem is, that for instance the download progress bar also uses it and therefore both switch places every few seconds in the ongoing area. Nevertheless you could be right about the FLAG_NO_CLEAR flag - have to test this although it won't solve my major problem. – ubuntudroid Jun 09 '11 at 08:00
  • FLAG_ONGOING_EVENT is only meant to indicate Android not to dismiss the notification. It has nothing to do with ordering – Vaiden Jan 08 '12 at 11:34
1

You say your notification displays a list of currently running apps. Why do you resend the notification every 3 seconds? Why not resend the notification only when the list of apps has changed. This doesn't directly solve your problem, but it drastically reduces it.

gotosleep
  • 328
  • 2
  • 9
  • You're absolutely right - I already implemented such a feature, but it doesn't work as intended at the moment. Therefore I temporarily switched back to the 3 minutes solution. Nevertheless, as you said, this wouldn't really solve my general problem... – ubuntudroid Jun 14 '11 at 07:46
-1

Just a note for other people that run into this issue -

Vaiden's answer fixed my issue where my ongoing notification kept jumping. It only happened to our app on ICS 4.0.3 for some reason, I think it's due to the fact that ICS handles notifications differently from the older versions. Also to note - on tablets, there are not "Ongoing" vs normal notification sections like on older versions (Gingerbread). The order is kept though, just not categorized. Not sure if it applies to phones on ICS.

aimango
  • 1,567
  • 2
  • 15
  • 29