51

I have made an app that sets notifications in the drop-down status bar of Android phones. However, there is a bug in my code (sometimes the notifications are set, sometimes they are not). I want to be able TO CHECK (in the code) IF THE NOTIFICATION IS VISIBLE TO THE USER. (i.e. can the user see the notification in the status bar?).

How can I do this? (Thanks in advance).

Sample code is greatly appreciated.

Yasir Malang
  • 835
  • 3
  • 10
  • 15

8 Answers8

49

I want to be able TO CHECK (in the code) IF THE NOTIFICATION IS VISIBLE TO THE USER. (i.e. can the user see the notification in the status bar?).

How can I do this?

You can't, sorry. Update: Now possible with Android 4.3+ http://developer.android.com/reference/android/service/notification/NotificationListenerService.html#getActiveNotifications()

However, you can always simply cancel() it -- canceling a Notification that is not on-screen is perfectly fine. Conversely, you can always safely call notify() again for the same Notification, and it too will not cause a problem if the Notification is already on-screen.

EDIT:

NotificationManager.getActiveNotifications() was added in API 23 if you don't want to use the NotificationListenerService

Smalls
  • 352
  • 3
  • 13
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • it will write again the Init text for the notification if you call notify again – weakwire Sep 02 '10 at 21:20
  • 1
    @weakwire: only if the notification was not already on-screen. – CommonsWare Sep 02 '10 at 21:37
  • didn't know that.Doesn't answer the question but serves the purpose with 2 lines of code. +1 – weakwire Sep 02 '10 at 22:38
  • 1
    Very useful information about calling notify() again - thanks! – Timmmm Jan 29 '12 at 18:21
  • 4
    It re-vibrates and makes the sound though. Is there any way around that? – Elad Nava Feb 02 '13 at 16:01
  • Do you only get your own notifications with this command, or *all*? – Nilzor Oct 02 '15 at 09:34
  • 3
    It sucks that I cannot get the status of notifs. posted by my own app without registering a `NotificationListenerService` (that requires the permission for listening to notifications). – Saket Jan 21 '16 at 10:24
  • @Saket It seems that it is now possible: http://stackoverflow.com/a/41891079/126574 – VitalyB Jan 27 '17 at 09:52
  • @VitalyB Sadly, only API 23+. It will take atleast 2 years before I can go minSdkVersion=23. – Saket Jan 27 '17 at 09:58
  • If the notification is of your app, you can use the "deleteIntent" parameter, too, to be notified about removal of the notification : https://developer.android.com/reference/android/app/Notification.html#deleteIntent . This can help too, right? – android developer Mar 29 '17 at 08:13
  • @CommonsWare : i have a group of notifications that shows unread messages. canceling each child is so simple. but when the last child canceled, the father group still is in status bar and it has no content. do you have any idea that can cancel father notification with it last child? tnx – MHSaffari May 12 '18 at 11:06
  • 1
    @MHSFisher: Sorry, but I do not understand your question. I recommend that you ask a separate Stack Overflow question, where you can provide a [mcve] and more details for your problem. – CommonsWare May 12 '18 at 11:54
31

Just to put all together. This is how it works

To build a notification,

        Notification n = new Notification.Builder(MyService.this)
                .setContentTitle("Notification Title")
                .setContentText("Notification Message")
                .setSmallIcon(R.drawable.myicon).build();

To make a notification sound call setSound() of Notification,

        Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        Notification n = new Notification.Builder(MyService.this)
                .setContentTitle("Notification Title")
                .setContentText("Notification Message")
                .setSound(alarmSound)
                .setSmallIcon(R.drawable.myicon).build();

To cancel the notification after user selected and launched the receiver Intent, call setAutoCancel(),

        Notification n = new Notification.Builder(MyService.this)
                .setContentTitle("Notification Title")
                .setContentText("Notification Message")
                .setSound(alarmSound)
                .setAutoCancel(true)
                .setSmallIcon(R.drawable.myicon).build();

To make sound/vibrate only once for a particular notification use Notification.FLAG_ONLY_ALERT_ONCE. With this flag, your notification will make sound only once till it gets cancelled and you can call notify() as many times as you want with the notification id. Note that if you call cancel() or if user cancelled the notification or auto cancelled, notify() call will make the notification sound again.

        n.flags |= Notification.FLAG_ONLY_ALERT_ONCE;    // Dont vibrate or make notification sound

Finally to put the notification on notification panel,

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        notificationManager.notify(notification_id, n);

Note that notification_id here is important if you want to use the notification effectively.( to keep single sound/vibration for a notification or to cancel a specific notification).

To cancel a particular notification,

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        notificationManager.cancel(notification_id);

You can cancel() a notification even if it doesn't exist or you can call notify() as many times as you want with the same id. Note that calling notify with different id will create new notifications.

So, regardless of whether the notification exist or not, if you call notify() again with the correct notification_id with the Notification.FLAG_ONLY_ALERT_ONCE flag set, you can keep your notification alive without disturbing the user with repeated sounds.

Naren Neelamegam
  • 1,625
  • 15
  • 15
28

You need to set an id for each notification you make.

so you make a notification ..

PendingIntent pendingIntent = PendingIntent.getBroadcast(this, notId + selectedPosition, intent, 0);

AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, rightNow.getTimeInMillis() - offset, pendingIntent);

Notification notification = new Notification(R.drawable.icon, "TVGuide Υπενθύμιση", System.currentTimeMillis());
NotificationManager manger = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
notification.setLatestEventInfo(context, "Κανάλι: " + b.getString("channel"), "Εκπομπή: " + showname, pendingIntent);
manger.notify(notId, notification);

to clear it..

PendingIntent pendingIntent = PendingIntent.getBroadcast(context,notId, intent, 0); 
pendingIntent.cancel();

and to check if active..( existAlarm returns null if no pending intent available)

 public PendingIntent existAlarm(int id) {
  Intent intent = new Intent(this, alarmreceiver.class);
  intent.setAction(Intent.ACTION_VIEW);
  PendingIntent test = PendingIntent.getBroadcast(this, id + selectedPosition, intent, PendingIntent.FLAG_NO_CREATE);
  return test;
 }

So everything comes down to initialize an ID for each notification and how you make it unique.

Ben H
  • 3,855
  • 1
  • 26
  • 33
weakwire
  • 9,284
  • 8
  • 53
  • 78
7

A new method is introduced to the NotificationManager class in API 23:

public StatusBarNotification[] getActiveNotifications()
dev.bmax
  • 8,998
  • 3
  • 30
  • 41
5

There exists a flag for that.

Notification notification = new Notification(icon, tickerText, when);
notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;

FLAG_ONLY_ALERT_ONCE:

...should be set if you want the sound and/or vibration play each time the notification is sent, even if it has not been canceled before that.

Although, the notification will blink when it is sent again, but there won't be any sound or vibration.

Abhishek Saini
  • 661
  • 11
  • 17
3

It's possible now to check notifications outstanding in android 4.3 upwards

See here:

http://developer.android.com/reference/android/service/notification/NotificationListenerService.html#getActiveNotifications()

Andrew
  • 7,548
  • 7
  • 50
  • 72
1

It seems that from Android M (API 23) it is possible to get your process like that, without using NotificationListenerService nor requiring additional permissions:

notificationManager.getActiveNotifications()

VitalyB
  • 12,397
  • 9
  • 72
  • 94
0

As of Android Marshmallow (API 23), you can recover a list of active notifications posted by your app. This NotificationManager method is getActiveNotifications(). More info here: https://developer.android.com/reference/android/app/NotificationManager.html#getActiveNotifications()

IgorGanapolsky
  • 26,189
  • 23
  • 116
  • 147