Similar to this post I got a service that does some work in the background. When the service starts, I'm displaying a notification. Usually you can assing an intent to the notification that is triggered when the user clicks onto the notification. Mostly an activity is then started.
But how can I use a notification to inform the background service that the user want's to cancel its operation?
You can have a BroadcastReceiver to stop the Service, which is triggered through the PendingIntent of the Notification.
Have a look at the PendingIntent.getBroadcast(...) and use it instead of the PendingIntent.getActivity() method. You can use it like this:
Intent broadcastIntent = new Intent(context, YourBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, broadcastIntent, 0);
Notification noti = new Notification.Builder(this)
...
.setContent(pendingIntent);
.build();
notification.setContent(pendingIntent);
The BroadcastReceiver could be an inner class in your Service to simply call stopService() in the onReceive() method.
Related
Using NotificationCompat.Builder, I am creating a incoming call notification, PRIORITY_HIGH notification with vibrate and ongoing set to true.
When notify() is called it also starts the ringtone player, playing the ringtone.
Currently this works perfectly. The answer and decline actions work fine, the only nuance is if you swipe away the notification, its demoted to the status bar (that is fine) but I also want the ringtone player to stop at this point.
Is there a way I can be told, or tell that the heads up notification has been swiped up into the status bar?
Answer in comment to accepted answer.
Problem was resolved by adding ringtone to the builder with .setSound(). Thanks A.A
what you need is a deleteIntent
deleteIntent
The intent to execute when the notification is explicitly dismissed by the user, either with the "Clear All" button or by swiping it away individually. This probably shouldn't be launching an activity since several of those will be sent at the same time.
You can set the PendingIntent to a BroadcastReceiver and then perform any action you want.
Intent intent = new Intent(this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, 0);
Builder builder = new Notification.Builder(this):
builder.setDeleteIntent(pendingIntent);
And for the BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// stop your ringtone here
}
}
I work with NotificationListener and I have a question.
Can I figure out if a notification was removed by the user and not by the app?
I believe you mean cleared by the user from the notification drawer. Yes you can get this information using setDeleteIntent()
The above mentioned API triggers a callback when the notification is cleared.
Intent finalIntent = new Intent(context, PushWorker.class);
finalIntent.putExtras(extras);
finalIntent.setAction(MoEPushWorker.NOTIFICATION_CLEARED);
PendingIntent intent =
PendingIntent.getService(context, 123, finalIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setDeleteIntent(intent);
Here PushWorker is the service in which the callback will be received.
Is there any way that when I click on the notification and then this notification can stop the service? And my notification is in my service.
Every time when I click on my notification, the activity will run onResume() method. I cannot stop this in this onResume() since I have another notification.
My app process is: a notification helps to tell the user it is now counting down the time, and when time is up, I will begin another notification to tell the user your time is up. So, I cannot stopservice before the "timeup" notification. My thought is, When the user click on "timeup" notification, then I can stop the service.
Can I do that?
The lifecycle of an application puts OnResume at the start of every launch, so the best method would be to assign a new request code to each new notification and give the one you wish to recognize an action. If the action is received, you can stop the service. If it is not, then the app will be able to differentiate that it is a different notification and respond accordingly.
...
Intent intent = new Intent(this, TARGET.class);
intent.setAction("CUSTOM_ACTION");
PendingIntent pIntent = PendingIntent.getService(this,
(int) System.currentTimeMillis(), intent,
PendingIntent.FLAG_UPDATE_CURRENT);
...
#Override
public void onResume(){
super.onResume();
if (getIntent().getAction().equals("CUSTOM_ACTION")) {
// kill service
} else {
// other stuff
}
}
I use NotificationCompat.Builder in an Activity and setAutoCancel(true) works fine, but the same is not working inside a BroadcastReceiver -the notification just keep showing up in the device regardless how many times the user clicks it. How to disable the notification upon user clicks in this case?
I also using this code together with the above and not working.
PendingIntent pi=PendingIntent.getActivity(context, 0, dailyIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Builder.setContentIntent(pi);
What you are doing is setting up an acitivity pending intent. It will launch activity upon clicking the notification. Change your PendinIntent to send broadcast like this:-
pi = PendingIntent.getBroadcast(context, 0, dailyIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
// notice getBroadcast()
where dailyIntent is an intent for broadcast. This will send the mentioned broadcast intent upon clicking the notification.
I am making an app where the user can set an alarm based on GPS location. I only want 1 alarm to be active at any one time. So, when the user sets a 2nd alarm, I want to cancel the notification for the 1st alarm (then set a new notification for the 2nd alarm).
Right now, my notifications continue to stack up (as in I can't delete them, so they are all active). Here is my code where I am trying to delete the alarm and notification(s):
// Stop the location alarm activity
Intent intentAlarmService_delete = new Intent(v.getContext(), AlarmService.class);
stopService(intentAlarmService_delete); // I think this calls onDestroy() in AlarmService class ...
mNtf = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNtf.cancelAll();
Intent alarmIntent2 = new Intent(getApplicationContext(), OneTimeAlarmReceiver.class);
PendingIntent pendingIntentAlarm = PendingIntent.getBroadcast(getApplicationContext(), PENDING_INTENT_REQUEST_CODE1,
alarmIntent2, PendingIntent.FLAG_CANCEL_CURRENT);
pendingIntentAlarm.cancel();
This is the onDestroy() function in my AlarmService.class (I'm not really sure when this is called...)
public void onDestroy(){
super.onDestroy();
mNtf.cancel(NOTIFICATION_ID1);
Intent alarmIntent = new Intent(getApplicationContext(), OneTimeAlarmReceiver.class);
PendingIntent pendingIntentAlarm = PendingIntent.getBroadcast(getApplicationContext(), PENDING_INTENT_REQUEST_CODE1,
alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
pendingIntentAlarm.cancel();
Intent intentAlarmService = new Intent(getApplicationContext(), AlarmService.class);
stopService(intentAlarmService);
mNtf.cancel(NOTIFICATION_ID1);
mNtf.cancelAll();
}
Then, this is how I am setting a new alarm and notification:
Intent intentAlarmService2 = new Intent(v.getContext(), AlarmService.class);
startService(intentAlarmService2);
By the way, my AlarmService.class is working for sure.
Thanks in advance.
First, get rid of getApplicationContext(). You almost never need it and it is frequently the wrong choice. Replace it with this, since whatever you are calling getApplicationContext() on is a Context.
In the code you have listed, you never raise a Notification. Hence, it is difficult to help you figure out why you are getting more than one. Calling cancelAll() on the NotificationManager should get rid of all outstanding notifications from your application.
My best guess is that onDestroy() is not being called on your service. That would occur if something else is keeping the service in memory (e.g., you have an active bound connection to it via bindService()). Or, possibly, you have something strange in your <service> element in the manifest (e.g., an unnecessary android:process attribute) that is fouling up the NotificationManager cancel() operation.
You need to make sure you are always referencing the same instance of your NotificationManager. Different instances will produce different notifications. I'd recommend using a service to manage notifications.
http://developer.android.com/guide/topics/fundamentals.html