16

I've got an for block which looks like this:

for(int counter = 0; counter < sList.size(); counter++){
            String s = sList.get(counter);
            Notification notification = new NotificationCompat.Builder(this).setContentTitle("Title").setContentText(s).setSmallIcon(R.drawable.ic_launcher).setContentIntent(pendingIntent).build();
            notification.flags |= Notification.FLAG_AUTO_CANCEL;
            notificationManager.notify(counter, notification);
}

This block is located in a service which is triggered by an alarmmanager. So this block may really well be executed a couple of times before the user sees the notifications. When this block is re-executed when something has been added to the sList, it overrides the current notifications, because the ID's of the notification are the same. How can I prevent that from happening? How can I get a unique ID every time? Or is there maybe possible to avoid the whole ID part, like telling android that is has to show the notification anyway, no matter what the ID is?

Thanks in advance!

Xander
  • 5,487
  • 14
  • 49
  • 77
  • Here's an easy way out while assuring uniqueness of Id : https://stackoverflow.com/a/58786832/8697587 – ImBatman Nov 10 '19 at 08:17

3 Answers3

22
long time = new Date().getTime();
String tmpStr = String.valueOf(time);
String last4Str = tmpStr.substring(tmpStr.length() - 5);
int notificationId = Integer.valueOf(last4Str);

notificationManager.notify(notificationId, notif);

It gets current system time. Then I'm reading only last 4 digits from it. I'm using it to create unique id every time notification is displayed. So the probability of getting same or reset of notification id will be avoided.

David
  • 3,392
  • 3
  • 36
  • 47
satyapol
  • 983
  • 11
  • 16
  • Would you mind adding an explanation to make us understand what your code does? – David Jan 31 '15 at 12:45
  • It gets current system time. Then I'm reading only last 4 digits from it. I'm using it to create unique id every time notification is displayed. So the probability of getting same or reset of notification id will be avoided. – satyapol Feb 03 '15 at 06:20
  • 2
    Thank you, I will add the explanation to your answer. [This answer explains why I wrote the first comment.](http://meta.stackoverflow.com/a/260413/213685) – David Feb 03 '15 at 09:47
  • 9
    You can use this instead: (int)((new Date().getTime() / 1000L) % Integer.MAX_VALUE) which gives you a new ID for each second and won't be repeated for 68 years, or without dividing it by 1000 gives you an ID for each microsecond and it won't be repeated for 24 days. – racs Jul 29 '15 at 03:35
12

I'm sure you shouldn't have so much of notifications for user at once. You should show a single notification that consolidates info about group of events like for example Gmail client does. Use Notification.Builder for that purpose.

NotificationCompat.Builder b = new NotificationCompat.Builder(c);
       b.setNumber(g_push.Counter)
        .setLargeIcon(BitmapFactory.decodeResource(c.getResources(), R.drawable.list_avatar))
        .setSmallIcon(R.drawable.ic_stat_example)
        .setAutoCancel(true)
        .setContentTitle(pushCount > 1 ? c.getString(R.string.stat_messages_title) + pushCount : title)
        .setContentText(pushCount > 1 ? push.ProfileID : mess)
        .setWhen(g_push.Timestamp)
        .setContentIntent(PendingIntent.getActivity(c, 0, it, PendingIntent.FLAG_UPDATE_CURRENT))
        .setDeleteIntent(PendingIntent.getBroadcast(c, 0, new Intent(ACTION_CLEAR_NOTIFICATION), PendingIntent.FLAG_CANCEL_CURRENT))
        .setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE)
        .setSound(Uri.parse(prefs.getString(
                SharedPreferencesID.PREFERENCE_ID_PUSH_SOUND_URI,
                "android.resource://ru.mail.mailapp/raw/new_message_bells")));

If you still need to have a lot of status bar notifications, you should save the last value of your counter somewhere and use for loop like this:

    int counter = loadLastCounterValue();
    for(String s : sList){
            Notification notification = new NotificationCompat.Builder(this).setContentTitle("Title").setContentText(s).setSmallIcon(R.drawable.ic_launcher).setContentIntent(pendingIntent).build();
            notification.flags |= Notification.FLAG_AUTO_CANCEL;
            notificationManager.notify(++counter, notification);
    }
    saveCounter(counter);

But as I have said I think it is bad solution that leads to bad user experience from your app.

kraxor
  • 649
  • 8
  • 16
rus1f1kat0R
  • 1,645
  • 1
  • 16
  • 22
  • using support libraries for building notifications, it is now possible to bundle (group) notifications together. https://developer.android.com/guide/topics/ui/notifiers/notifications.html#bundle – Raphael C Dec 13 '16 at 13:23
9

you can simply specify an id in the notification builder.
Same id = update of the notification
different id = new notification.

Also, two different apps can use the same notification id, it will spawn 2 different notifications without issue. the system look at both the id & the app where it comes from.

Teovald
  • 4,369
  • 4
  • 26
  • 45