I want to delete a notification which is located on my status bar. I used Notification Manager.cancel() but it didn't work. I used cancelAll() too with the same result.
My code is:
public class NotificationListenerService extends android.service.notification.NotificationListenerService {
...
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
NotificationManager nManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nManager.cancel(sbn.getId());
nManager.cancel(sbn.getTag(), sbn.getID());
nManager.cancelAll();
}
I found more answers here on SO but none solved my issue. The sbn object is right, I print in my log all its data.
It's possible to delete an exiting notification located on the status bar with Android API < 20? (so without using cancelNotification())
With API >= 21, you can try use the method cancelNotification (String key)
With API < 21, you can try use the method cancelNotification (String pkg, String tag, int id)
Related
I have a foreground service which is used to upload file and show the progress of it via notification.
The code below I'm posting works pretty good, except that on every update event, it vibrates.
My code to start a foreground service and init the notification is as below.
//this method is called on onStartService().
void startForegroundService() {
mCompatBuilder.setSmallIcon(R.drawable.img_checkbox);
mCompatBuilder.setContentIntent(pendingIntent);
mCompatBuilder.setTicker("Ticker");
mCompatBuilder.setWhen(System.currentTimeMillis());
mCompatBuilder.setContentTitle("Uploading");
mCompatBuilder.setProgress(100, 0, false);
mCompatBuilder.setContentText("0%");
mCompatBuilder.setContentIntent(pendingIntent);
mCompatBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
mCompatBuilder.setPriority(NotificationCompat.PRIORITY_LOW);
mCompatBuilder.setOngoing(true);
mCompatBuilder.setAutoCancel(false);
mCompatBuilder.setVibrate(new long[]{0L});
startForeground(1, mCompatBuilder.build());
}
The progress update part is as below.
public void updateProgress(int progress, String contentText) {
mCompatBuilder.setContentText(contentText);
mCompatBuilder.setProgress(100, progress, false);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mCompatBuilder.build());
}
I've tried to lower the priority of the notification, and also tried to set the setVibration to new long{0L}. But neither of it seems to be working.
What else can I try? Please help!
Can you try removing this line? mCompatBuilder.setVibrate(new long[]{0L});
I want to remove all cancelable notifications from status bar. I know how to remove my app notifications I have seen this post before, butI want to remove other apps notifications.
There is a "Clear" button in notifications in all android versions which clears all notifications with this flag: Notification.FLAG_AUTO_CANCEL
That means it's possible to cancel all notifications. But I haven't found any document about how to do that. Is there anybody guide me how to do that?
Thanks
Starting with API Level 18 you can cancel Notifications posted by other apps different than your own using NotificationListenerService, the method changed a little in Lollipop, here is the way to remove notifications covering also Lillipop API.
First inside the onNotificationPosted method you store all the StatusBarNotification objects.
Then you should maintain an updated reference to those objects, removing them if the notification is somehow dismissed in onNotificationRemoved method.
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class NotificationService extends NotificationListenerService {
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
// Store each StatusBarNotification object
}
#Override
public void onNotificationRemoved(StatusBarNotification sbn) {
// Delete removed StatusBarNotification objects
}
}
Finally you can remove any notification using cancelNotification method.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
cancelNotification(sbn.getPackageName(), sbn.getTag(), sbn.getId());
}
else {
cancelNotification(sbn.getKey());
}
To remove all notifications:
Kotlin
val NM = getSystemService(AppCompatActivity.NOTIFICATION_SERVICE) as NotificationManager
NM.cancelAll()
Java
NotificationManager NM = getSystemService(AppCompatActivity.NOTIFICATION_SERVICE)
NM.cancelAll()
Ive looked around and found some examples of using the new notificationlistenerservice class, but im having issues with it not even hearing the notification post event.
the examples that im finding are using a gui and broadcast receivers which arent really needed by my goal.
im trying to fire off toast notifications at least with this, but i get nothing. i have verified that the application is allowed to listen to notifications and has notifications enabled.
Anything im missing?
//listen for new notifications?
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
Toast.makeText(getApplicationContext(), sbn.getPackageName().toString(), 1).show();
Toast.makeText(getApplicationContext(), "anything? anything? please?", 1).show();
}
//listen for the removal of the notities
#Override
public void onNotificationRemoved(StatusBarNotification sbn) {
//uhh not done yet
}
//prepare
public void onCreate() {
super.onCreate();
//ongoing notification test, is this needed for notification listeners?
NotificationManager notificationManager;
Notification myNotification;
Context context = getApplicationContext();
myNotification = new Notification.Builder(context)
.setContentTitle("NotifyWake")
.setSmallIcon(R.drawable.ic_notification_open)
.setOngoing(true)
.build();
notificationManager = (NotificationManager)getSystemService(context.NOTIFICATION_SERVICE);
notificationManager.notify(1, myNotification);
//end ongoing notification
}
Figured it out, you must create some threaded or broadcasted method to offload anything from the post/removed events. things like toast do not work since the method fires off a threading error and silently fails(noted in logcats)
so, a simple solution is to extend broadcastreceiver and pass the heavy lifting and gui stuff to that method.
I've had a problem with NotificationManager in my app for the past couple of days and I don't seem to be getting closer to solving it.
I have a very simple service which does not do anything at the moment. It is just supposed to display notification:
public class UpdateService extends Service {
private static final String TAG = "UpdateService";
private static int NOTIFICATION_ID = 1;
private UpdateServiceBinder binder = new UpdateServiceBinder();
#Override
public void onCreate() {
Log.i(TAG, "Service created");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service started");
sendNotification(100);
return Service.START_NOT_STICKY;
}
private void sendNotification(int updatedItems) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.icon)
.setContentTitle("Sync")
.setContentText("Updated " + updatedItems);
Intent resultIntent = new Intent(getBaseContext(), MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(getApplicationContext());
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendindIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(resultPendindIntent);
NotificationManager manager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(NOTIFICATION_ID, builder.build());
}
#Override
public IBinder onBind(Intent intent) {
return binder;
}
#Override
public boolean onUnbind(Intent intent) {
return true;
}
public class UpdateServiceBinder extends Binder {
public UpdateService getService() {
return UpdateService.this;
}
}
}
Unfortunately, when the service is started and the notification is supposed to be displayed nothing happens. The service is definitely started according to log messages. At the same time there is warning from NotificationManager:
11-30 23:24:34.620: I/UpdateService(28356): Service created
11-30 23:24:34.800: I/UpdateService(28356): Service started
11-30 23:24:34.808: W/NotificationManager(28356): notify: id
corrupted: sent 1, got back 0
I tried using different numbers than 1 but it did not help. I am not sure what to make out of it. The code I'm using comes from the Android documentation on service in here and notifications in here. When I isolate the code in separate clean app which is setup in similar way to the one I'm working on notification is displayed correctly. Has anybody had this problem before or has any ideas?
Any help appreciated.
Thanks!
I had this problem then I remember that I had disabled the "Show Notification" from my "App info". I enabled it and notifications are back again.
Go to Settings > Apps (Application Manager).
Tap the app you want to stop.
Tap to uncheck the box for Show notifications.
FYI it might differ from one android device to the other, however they are all more or less the same.
Startin from API 25 (Nougat), Android puts rate limiting in place to block apps from DDOSing the notification shade. The commits to AOSP introducing this change can be seen here.
I was seeing these logs on my side because I was trying to update a progress notification inside a loop:
Observable.range(0, 100)
.subscribe(progress -> updateProgressNotification(progress));
Adding an delay of 200ms between each emission fixes the problem for me:
Observable.range(0, 100)
.zipWith(Observable.interval(200, TimeUnit.MILLISECONDS), (progress, delay) -> progress)
.subscribe(progress -> updateProgressNotification(progress));
You can read more about this problem on my blog.
I found a solution to this problem. I had to change the package name from com.gttn.sample to com.gttn.sample2. Not really sure why I had to do it but the notifications show properly and the warning disappeared.
When you install and reinstall the app many times something
unchecked the "Show Notifications" in Settings > ApplicationManager > "Your app".
Just check again "Show Notifications" and be happy!
I'm not sure why you're using getBaseContext(), but I suggest you use getApplicationContext() instead. Also, I'm not sure why you're binding to the Service.
just looked into this problem myself. without additional lines from your logfile (should be within 5 lines after) there might be a message similar to "E/NotificationService( 287): Suppressing notification from package by user request." This is a new setting in ICS (maybe JB) to disable notifications on a per-app basis. Go to Settings --> Apps --> and click the checkbox "show notifications" near the top. for obvious reasons, changing the package name would circumvent this setting very effectively.
I have written code which download the song and update the progress of the download as the progress in the notification. If u see in the line 6 of code ,If that condition is removed then notification is updated very fast as the while loop reads the bytes from the input stream now this causes repeated updates on the notification and this is recognised as the problem starting from noughat verions which keeps the rate limit on the notification update.Hope you got some idea about it.
int previousPercentage = 0;
int currentPercentage = 0;
while ((bytesRead = inputStream.read(bytes)) != -1) {
totalbytes = totalbytes + bytesRead;
currentPercentage = (totalbytes * 100) / length_of_file;
if (previousPercentage != currentPercentage) {// line : 6
updateProgressNotification(builder, notificationId, currentPercentage);
}
previousPercentage = currentPercentage;
fileOutputStream.write(bytes, 0, bytesRead);
}
Android: I am trying to cancel a notification from the notification bar after a package being installed.
What I am doing is the following:
public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
Uri data = intent.getData();
//some code goes here
//get the id of the notification to cancel in some way
notificationhelper._completeNotificationManager.cancel(id);
}
}
}
where
public class notificationhelper {
public static NotificationManager _completeNotificationManager = null;
public void complete() {
if (_completeNotificationManager == null)
_completeNotificationManager = (NotificationManager) _context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(
R.drawable.notification,
_context.getString(R.string.notification),
System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.flags |= Notification.FLAG_NO_CLEAR;
_completeNotificationManager.notify(TEXT, id, notification);
}
}
But the notificationhelper._completeNotificationManager.cancel(id) does not work. I tried to use notificationhelper._completeNotificationManager.cancelAll(); and it works. What I am doing wrong?
In my experience, you can't cancel all notifications with a particular ID, regardless of tag.
That is, if you create two notifications like so:
notificationManager.notify(TAG_ONE, SAME_ID, notification_one);
notificationManager.notify(TAG_TWO, SAME_ID, notification_two);
Then, notificationManager.cancel(SAME_ID) won't cancel either of them! I suspect that this is because the "tag" field, if unspecified in notify() and cancel(), defaults to null, which you have to cancel explicitly.
So, to cancel these two notifications, you have to call:
notificationManager.cancel(TAG_ONE, SAME_ID);
notificationManager.cancel(TAG_TWO, SAME_ID);
In your case, you're supplying "TEXT" as the tag but cancelling just using the id, which defaults to using tag=null.
So, either don't provide TEXT as your tag:
_completeNotificationManager.notify(id, notification);
Or, if you need separate notifications and don't want them to clobber each other, keep track of the active tags:
_completeNotificationManager.notify(TEXT, id, notification);
collectionOfActiveTags.add(TEXT);
...
for (String activeTag : collectionOfActiveTags)
notificationhelper._completeNotificationManager.cancel(activeTag, id);
I wish that what you're trying to do was supported, as it seems that it should be.
Well this is probably irrelevant at this point, but it should be posted here so that people like me dealing with the same problem might find the solution.
If NotificationManager.cancel() isn't working, try changing the ID for the notification.
notificationManager.notify(NOTIFICATION_ID, notification);
When I changed NOTIFICATION_ID from 1 to [RANDOM_NUMBER], it magically started working. I assume that 1 is somehow reserved, although there is no note in any documentation...
An of course make sure you use the same NOTIFICATION_ID to cancel:
notificationManager.cancel(NOTIFICATION_ID);
My notifications were not getting removed because my service was Foreground Service and NOT a regular service started by StartService.
If your service is foreground, call stopForeground(true) instead of stopself(). So now my code looks like this:
NotificationManagerCompat.from(this).cancel(NotificationHelper.PLAYER_NOTIFICATION_ID);
stopForeground(true);
and it worked, notification was removed.
I was facing the same issue recently. I have managed to solve it.
So from what i understood.
use the id which is basically a random number to notify and send this same id to the piece of code (receiver/activity...) where you want to cancel it.
When using tags, it seems to not work for me as I was giving one tag to all notifications but with unique id. It worked only on the first tag so I completely avoided using tags. If you want to use tags, issue unique tags along with unique id and use them both while cancelling.
So final answer... what I used and what works for me:
STEP 1:
int notif_id = (int)(System.currentTimeMillis()%10000);
STEP2: add this id inside the action intent (I am launching an activity where the notification gets cancelled on the action click):
Intent notificationSettingsIntent = new Intent(context.getApplicationContext(), NotificationSettingsActivity.class);
notificationSettingsIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
notificationSettingsIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
notificationSettingsIntent.putExtra("fromNotification",true);
notificationSettingsIntent.putExtra("notif_id",notif_id);
PendingIntent notificationSettingsActivityPendingIntent = PendingIntent.getActivity(context,notif_id,notificationSettingsIntent,PendingIntent.FLAG_ONE_SHOT);
STEP 3: notify using the id in the step 1 but with no tags
NotificationManagerCompat notificationCompat = NotificationManagerCompat.from(context.getApplicationContext());
notificationCompat.notify(notif_id,notificationBuilder.build());
Now in the Activity which gets opened by my action click, I cancel the notification as:
NotificationManagerCompat notificationCompat = NotificationManagerCompat.from(context.getApplicationContext());
notificationCompat.cancel(getIntent().getIntExtra("notif_id"));
Works every time now.
Sorry for late joining!
But following worked fine for me.
NotificationManagerCompat mNotificationManager = NotificationManagerCompat.from(context.getApplicationContext());
mNotificationManager.cancel("<TAG>",<Notificatoin-id>);
Following worked for me:
final NotificationManagerCompat mNotificationManager = NotificationManagerCompat.from(context.getApplicationContext());
mNotificationManager.cancel(<Notificatoin-id>);
Since there is no accepted answer, I am posting another one with same scenario I faced
private fun stopForegroundService() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
stopForeground(STOP_FOREGROUND_DETACH)
}else if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N){
stopForeground(true)
}
notificationManager.cancel(NOTIFICATION_ID)
}
Point to note is first you need to set stopForeground(false) then call notificationManager.cancel(NOTIFICATION_ID)
If you change the order, it won't work