I'm creating a notification with a pendingIntent that opens CallActivity:
NotificationCompat.Builder(context, Constants.CALL_NOTIF_ID)
.setSmallIcon(R.drawable.my_ic)
.setOngoing(true)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setSound(null)
.setVibrate(LongArray(0))
.setCategory(NotificationCompat.CATEGORY_CALL)
.setContentIntent(myPendingIntent)
.setStyle(NotificationCompat.DecoratedCustomViewStyle())
Im showing this notification while the call is active And clearing it when the call stops with this code:
notificationManager.cancel(Constants.CALL_NOTIF_ID)
Now when I call a device and immediately stop the call, notification appears but it takes 1-2 seconds to disappear. In this short time user can click on notification and can see the CallActivity.
Actually I can make an if check to close activity if there is no call but I don't want to open it in the first place.
So how can I remove the notification immediately without animation (even with reflection)?
Related
I'm making an app that communicates to an Aurdino through bluetooth. It uses a service for the communication part. So as long as the service is running, I want a notification to be shown by the app. The user shouldn't be able to swipe the notification to make it go away.
Here's my notification function so far:
void showNotification(String title, String contentText)
{
...
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext(), "default")
.setSmallIcon(R.mipmap.ic_launcher) // notification icon
.setContentTitle(title) // title for notification
.setContentText(content)
.setAutoCancel(false)
.setOngoing(true);
mNotificationManager.notify(0, mBuilder.build());
}
Notice that I've called the setOngoing(true) but still I can swipe the notification from the notification drawer and it goes away when I do so.
How do I prevent the user from being able to swipe and cancel the notification? My app will automatically cancel it when it is terminated, in the OnDestroy() of the service.
You need to make a foreground service, while your service is active its notification too
So your service becomes so hard to be killed by the system
https://www.dev2qa.com/android-foreground-service-example/
I have a written a service which fires a notification with an alarm ringtone at a specific time. The notification works as intended, however, the problem is that even after I cancel the notification or click on it from the notification bar, it continues to play the ringtone. Meaning that the notification cancels if I swipe across it, and it opens a pending intent if I click on it. However, the sound/ringtone keeps on playing even after I have performed either of the aforementioned actions (swipe, click).
My code for firing the notification is as follows (it's written in Kotlin):
private fun fireNotification() {
var anotherIntent:Intent=Intent(this,ReminderActivity::class.java)
var p1:PendingIntent= PendingIntent.getActivity(this,0,anotherIntent,0)
val defaultSoundUri=RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
var notifyManager: NotificationManager =getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
var notification:Notification=NotificationCompat.Builder(this)
.setContentTitle("Medicine Time")
.setSmallIcon(R.mipmap.ic_launcher)
.setSound(defaultSoundUri)
.setContentText("Time to take your medicine")
.setContentIntent(p1)
.setAutoCancel(true)
.build()
notifyManager.notify(0,notification)
}
Any help in the matter would be greatly appreciated, thanks!
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
long when = Calendar.getInstance().getTimeInMillis();
when += 10000;
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(
getApplicationContext())
.setWhen(when)
.setContentText(notificationContent)
.setContentTitle(notificationTitle)
.setSmallIcon(smalIcon)
.setAutoCancel(true)
.setTicker(notificationTitle)
.setLargeIcon(largeIcon)
.setDefaults(Notification.DEFAULT_LIGHTS| Notification.DEFAULT_VIBRATE| Notification.DEFAULT_SOUND)
.setContentIntent(pendingIntent);
This runs in the onCreate, however, my notification gets created instantly when the app starts, rather then after 10 seconds.
Whats wrong ?
Even
.setWhen(System.currentTimeMillis()+10000)
does not make it show after 10 seconds. it shows directly.
From the documentation for setWhen(...)...
Add a timestamp pertaining to the notification (usually the time the event occurred). It will be shown in the notification content view by default; use setShowWhen to control this.
The setWhen(...) method doesn't set a time (delay) for when a Notification should be displayed. It's used to show the time that some event has occured.
For example, suppose your app monitors receiving SMS messages - when a message arrives you would create a Notification saying "You have a new SMS message" and you'd use setWhen(...) to show the time that the message was received.
If you want to set a particular delay or fixed time for an event to occur and an associated Notification to be shown, use AlarmManager.
I've been trying to remove a persistent Notification set by a Service using:
startForeground(1337, notification);
The code I'm using to cancel it:
NotificationManager nManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nManager.cancel(1337); // cancel existing service notification, doesn't take effect
nManager.cancelAll(); //surpluous, but also doesn't take effect
To clarify why I am doing this: the Service starts with a default persistent Notification. When my app runs, it needs to replace this Notification with another. Using notify() on the existing Notification works perfectly, however, I need it to show the ticker text for the new Notification as well. This is why I decided to remove the existing Notification (using the code above), create a new one, and then I call startForeground() again and pass the new Notification to it, so my Service persists.
The problem is that you're issuing the Notification in an indirect way by using startForeground(). You can't just cancel that Notification for the same reason the system insists on you providing a Notification when starting a foreground Service. As long as your foreground Service is running, that Notification will be there.
In most cases, Services really shouldn't be in the foreground. If you can use a normal priority for your Service, then you can start and stop your Notification normally.
If you're actually doing something that truly does require a foreground Service, and if you really want to show the user a ticker text, I believe your only option is to issue another Notification.
You can always remove notification from a foreground service by callng stopForeground(boolean removeNotification). Then a service exits his foregroundState and once again can be killed by the system when the memory is needed.
You could update the notification by passing in an empty Builder.
if(showNotification){
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setVisibility(Notification.VISIBILITY_SECRET)
.setSmallIcon(R.mipmap.ic_spotify_white_24dp)
.setTicker("Playing Now")
.setContentTitle("Spotify")
.setContentText("Preview");
return mBuilder;
}else{
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
return mBuilder;
}