What's the best way to clear the notification number when the user clicks on the notification? I say the best way, but really I haven't found ANY way. I'm launching a built in activity when the user clicks on the notification, not something I wrote so I can't clear it that way. I've got the notification manager's flag set to clear
NotificationManager notification
.
.
.
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.number++;
nm.notify(1,notification);
But whatever I do the Notification.number keeps going up and never resets to 0.
You could use an intermediary activity which is part of your app and thus can reset your variable and then start the internal activity.
So the chain would be
Notification --starts--> Intermediary Activity --starts--> Built-in activity
I am using a combination of what #CommonsWare recommends and extending an application object as here How to update notification number .
Edit: Further testing shows that actually this is not working because the BroadcastReceiver is called on every notification and because it reset the number on every notification the number is never correct.
Related
I have an Alarm App that have foreground service with a Heads-Up Notification and that notification have two actions where one send an intent to the Service and can open an activity depending on the app configuration.
The problem is that when i click on a action that sends the intent to the service the notification doesn't hide. This not seems to occur when the intent opens a Activity
I don't want a foreground service without a Notification, i just want it to hide it back to the Notification Drawer when the intent is sent to the service
Here is the code:
NotificationCompat.Builder(mAlarmApplication, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification_alarm)
.setAutoCancel(false)
.setOngoing(true)
.setVibrate(LongArray(0))
.setContentTitle("Title")
.setContentText("Content")
.addAction(0, dismissActionText, dismissPendingIntent)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContentIntent(alarmScreenPendingIntent)
.setFullScreenIntent(alarmScreenPendingIntent, true)
Here is the link of the app https://play.google.com/store/apps/details?id=com.garageapp.alarmchallenges.
The problem occurs when alarm start and my current solution is to update the old heads up notification with a new one that is not a heads up but the UX is not a good because on Android 8+ the notification new notification pops up aging
Seems like your Notification is bonded with your Service. If so, then you have to kill the notification in Service
Did you try?
public static void cancelNotification(Context ctx, int notifyId) {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager nMgr = (NotificationManager) ctx.getSystemService(ns);
nMgr.cancel(notifyId);
}
You are using .setOngoing(true) which should not be removed while service is working.
.setAutoCancel(true) will also not working with .setOngoing(true).
You have to use .setOngoing(false) to dismiss the notification.
If you or user remove your foreground notification your service will go to background, I think that best work is to not using heads up notification for foreground by not setting its priority to MAX
Use two notifications at same time one in drawer and another heads up:
-The first notification with priority DEFAULT for starting foreground ( auto cancel set to false and ongoing set to true) show this one with startForground()
-The Second notification (Heads up (Priority MAX) auto cancel set to true and on going set to false) for your actions show this with notifyManager.notify()
These two notifications must have different IDs
another solution:
If you want to use one heads up notification with actions for foreground service you may do this:
use a heads up notification with your action buttons for foreground service when the user clicks actions this action must call the foreground service and then the foreground service could call startForeground (with same id) with a new notification with priority set to default, if your notification could not be updated you may need to call stopForeground(true) or notificationManager.cancel(id) first before calling startForeground with new notification. both of these two notifications should has on going set to true and auto cancel set to false
In my opinion the first solution is better than the second because the notification may not update in second solution.
As the documentation says :
A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of ...
android system does not allow you to have a foreground service without notification or a hidden notification. and that's because of user awareness of what is happening in his/her system.
also killing the notification will stop your foreground service.
so you never can have both of the options (foreground service and hidden notification)
a not clear solution for your problem:
when you call action that sends the intent to the service, do this with a mediator activity i mean first open an activity and in the activity send intent to the service.
I hope this solve your problem as you told :
The problem is that when i click on a action that sends the intent to the service the notification doesn't hide. This not seems to occur when the intent opens a Activity
After a long search, I was not able to find exactly what I need.
I simply want : When a notification is displayed to the user, if the app is simply in background I want to reopen MainActivity. But if the app/activity has been killed, I want to restart the app completely.
My actual code :
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle(notification.getSubject())
.setContentText(notification.getMessage())
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI);
mBuilder.setContentIntent(
PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_UPDATE_CURRENT));
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notif = mBuilder.build();
notif.flags = Notification.DEFAULT_VIBRATE | Notification.FLAG_AUTO_CANCEL;
Case which is not working actually is to restart the app if app or activity has been killed.
EDIT : By killed I mean the app has been closed in the app manager. Or we lost the focus and the activity is destroyed. In those cases I would like to fully restart the app.
I think you don't entirely understand how android functions. Whenever your program is needed, the program is started by android (See the Application class for an onCreate that you can override).
Whenever an activity is necessary it is (re)created or brought to the foreground.
That means that an activity restart does not necessarily imply a restart of the application. In practice, if the program was still in memory, then an application restart won't happen.
If you want to investigate this further
create an Application.onCreate method so you see whether your app is restarted or not.
trigger the notification
go to the android settings, application tab, and there select 'show cached processes'. Clear your process from the list.
tap the notification.
This should trigger a restart of the application. If this is indeed the problem then you cannot 'solve' it. Android decides when it will kill your application and when it removes it from memory.
The best solution then is to redesign your activity that whatever the application restart would trigger is also performed in the activity itself. Or so, without more detail what functionality you would like to see performed on an 'activity/application-restart' it is difficult to advice further on this matter.
I think you need to change your setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) value to setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT).
The reason is due to the way that FLAG_ACTIVITY_REORDER_TO_FRONT
works. When you use this flag, Android looks for an instance of the
desired activity in your activity stack, starting from the front of
the stack and scanning until it gets to the root/back of the stack. As
soon as it finds an instance of the specified activity, it brings that
one to the front (ie: if there are multiple instances of the specified
activity it will bring to the front the most recent instance).
Original I found here.
See android developer doc here.
I hope its help you.
I need to remove the notification.without affecting the foreground service of the application.thanks in advance
Notification note = new Notification(R.drawable.ic_blank,"",System.currentTimeMillis());
Intent i=new Intent(this, MyLocationListener.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi=PendingIntent.getActivity(this, 0,i, 0);
note.setLatestEventInfo(this, "","", pi);
note.flags |= Notification.FLAG_NO_CLEAR;
startForeground(42, note);
Android OS don’t like you to do this because users are entitled to know you are running a foreground serivce on their devices.
But if you must remove notification of foreground service :
In order to remove the notification icon in the notification area (the status bar) while foreground service still running :
Just set the priority to minimum (-2) in the notification builder:
for example:
/* (Notification.PRIORITY_MIN) will remove the notification in statusbar */
builder.setPriority(Notification.PRIORITY_MIN)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Service Started")
.setTicker("Music Playing")
.setWhen(System.currentTimeMillis());
This will only remove the small notification icon in the notification area.
if you also need to get rid of the detail notification rectangle in the notification drawer :
then what you need to do is more complex:
you need to start your service as foreground, then start another foreground service with the same notification ID as you have in your original service.
Then close ( stopself() ) the new foreground service, and Android system will remove the notification (while your original service that started previously will stay in foreground without the notification).
This works fine in 5.1.1, I don’t know if android team already close this breach in marshmallow .
BTW:
In order to do this there is also a non-programmatically way :
Go to settings -> applications -> application manager find your application and press on it.
You will get inside your application info.
Disable the “show notifications” option in your application info.
This will get rid of all notifications for your app but it also disable toast messages..
I don’t think there is a way to disable this option in settings programmatically from inside the application - I think android prevent it for security reasons. If anyone knows how to change this programmatically please tell..
if while trying to avoid the notification detail rectangle in the drawer you will remove these lines in your notification builder:
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Service Started")
.setTicker("Music Playing")
.setWhen(System.currentTimeMillis());
Then Android system will keep on showing a notification rectangle about your service (with the title “This service is running, touch for more information or stop the service ” ) and pressing on this rectangle will lead the user to Your application info on settings -> applications -> application manager with option to “force stop” this service.
Regarding that you can read more here https://plus.google.com/105051985738280261832/posts/MTinJWdNL8t
hope it helps :-)
Adding this line builder.setPriority(Notification.PRIORITY_MIN) will remove the notification icon from the status bar and lock screen.
Also removing or commenting builder.setSmallIcon(R.drawable.ic_launcher) removes the notification icon even when you scroll down notifications when device is unlockedbut i m not sure how it will work in android N
I have an ongoing task and after it finishes, I want the notification to become cancelable.
For that, I create a new notification with notification.flags as zero, but the notification keeps being un-cancelable.
Apparently, FLAG_FOREGROUND_SERVICE prevented the notification from turning into cancelable, even after reseting the flags.
After removing FLAG_FOREGROUND_SERVICE and using only 0 or FLAG_ONGOING_EVENT, the notification could be made cancelable or un-cancelable - respectively.
Please take a look here : Android update notification
In short what you will do is this:
Create your notification first time and assign a notification ID to it.
Once your service is done executing create a new cancelable notification with the same id
fire that notification, it should make the previous notification cancelable .
I would like to animate the icon of the app without having to cancel the notification and create a new one (because in this way the icon doesn't stay in the same position of the notification bar but could move to first place if there are other notification running).
I'm able to get this with normal notification, but I would like to get the same behaviour when I use startForeground in my service. This method launches a new notification which can't be removed unless you remove service from foreground using stopForeground.
Is this possible to do? How?
Use the same notification ID for the startForeground method and the Notification object.