catch on swipe to dismiss event
Asked Answered
M

3

91

I'm using an android notification to alert the user once a service is finished (success or failure), and I want to delete local files once the process is done.

My problem is that in the event of failure - I want to let the user a "retry" option. and if he chooses not to retry and to dismiss the notification I want to delete local files saved for the process purposes (images...).

Is there a way to catch the notification's swipe-to-dismiss event?

Mahon answered 3/2, 2013 at 10:19 Comment(0)
S
149

DeleteIntent: DeleteIntent is a PendingIntent object that can be associated with a notification and gets fired when the notification gets deleted, ether by :

  • User specific action
  • User Delete all the notifications.

You can set the Pending Intent to a broadcast Receiver 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):
 ..... code for your notification
  builder.setDeleteIntent(pendingIntent);

MyBroadcastReceiver

public class MyBroadcastReceiver extends BroadcastReceiver {
      @Override
      public void onReceive(Context context, Intent intent) {
             .... code to handle cancel
         }

  }
Stanfield answered 3/2, 2013 at 10:39 Comment(3)
This is late. I was just wondering if there is a similar approach for notifications which had builder.setAutoCancel(true); becuase when a user clicks the notification and it is cancelled, delete-Intent is not triggeredSikorski
@dev_android checkout developer.android.com/reference/android/app/…Stanfield
@Peter In order to get it to work in Oreo and Obove you need to add this line of code: Notification note = builder.build(); note.flags |= Notification.FLAG_AUTO_CANCEL;Simonne
R
91

A fully flushed out answer (with thanks to Mr. Me for the answer):

1) Create a receiver to handle the swipe-to-dismiss event:

public class NotificationDismissedReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
      int notificationId = intent.getExtras().getInt("com.my.app.notificationId");
      /* Your code to handle the event here */
  }
}

2) Add an entry to your manifest:

<receiver
    android:name="com.my.app.receiver.NotificationDismissedReceiver"
    android:exported="false" >
</receiver>

3) Create the pending intent using a unique id for the pending intent (the notification id is used here) as without this the same extras will be reused for each dismissal event:

private PendingIntent createOnDismissedIntent(Context context, int notificationId) {
    Intent intent = new Intent(context, NotificationDismissedReceiver.class);
    intent.putExtra("com.my.app.notificationId", notificationId);

    PendingIntent pendingIntent =
           PendingIntent.getBroadcast(context.getApplicationContext(), 
                                      notificationId, intent, 0);
    return pendingIntent;
}

4) Build your notification:

Notification notification = new NotificationCompat.Builder(context)
              .setContentTitle("My App")
              .setContentText("hello world")
              .setWhen(notificationTime)
              .setDeleteIntent(createOnDismissedIntent(context, notificationId))
              .build();

NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationId, notification);
Rarotonga answered 18/12, 2013 at 23:55 Comment(4)
Didn't worked for me, always resulted with error "Unable to instantiate receiver .... has no zero argument constructor". Solved only after I've implemented another similar solution but with registering of broadcast receiver: #13028622Flout
This works for me.But the event can't be invoked when you click the notification.How could i listen the click event?Confederation
According to the docs, if you use setAutoCancel(true), then the notification will be canceled when clicked and also broadcast the delete intent [developer.android.com/reference/android/support/v4/app/…Aeriform
This works, except the parameter passing, intent.getExtras() always returns null, even if extras are set. For it to work, you have to set action like so : resultIntent.setAction(unique_action);Wilie
L
0

Another Idea:

if you create a notification normally you also need the actions one, two or 3 of them. I've created a "NotifyManager" it creates all notifications i need and also receive all Intent calls. So i can manage all the actions AND also the catch the dismiss event at ONE place.

public class NotifyPerformService extends IntentService {

@Inject NotificationManager notificationManager;

public NotifyPerformService() {
    super("NotifyService");
    ...//some Dagger stuff
}

@Override
public void onHandleIntent(Intent intent) {
    notificationManager.performNotifyCall(intent);
}

to create the deleteIntent use this (in the NotificationManager):

private PendingIntent createOnDismissedIntent(Context context) {
    Intent          intent          = new Intent(context, NotifyPerformMailService.class).setAction("ACTION_NOTIFY_DELETED");
    PendingIntent   pendingIntent   = PendingIntent.getService(context, SOME_NOTIFY_DELETED_ID, intent, 0);

    return pendingIntent;
}

and THAT i use to set the delete Intent like this (in the NotificationManager):

private NotificationCompat.Builder setNotificationStandardValues(Context context, long when){
    String                          subText = "some string";
    NotificationCompat.Builder      builder = new NotificationCompat.Builder(context.getApplicationContext());


    builder
            .setLights(ContextUtils.getResourceColor(R.color.primary) , 1800, 3500) //Set the argb value that you would like the LED on the device to blink, as well as the rate
            .setAutoCancel(true)                                                    //Setting this flag will make it so the notification is automatically canceled when the user clicks it in the panel.
            .setWhen(when)                                                          //Set the time that the event occurred. Notifications in the panel are sorted by this time.
            .setVibrate(new long[]{1000, 1000})                                     //Set the vibration pattern to use.

            .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
            .setSmallIcon(R.drawable.ic_white_24dp)
            .setGroup(NOTIFY_GROUP)
            .setContentInfo(subText)
            .setDeleteIntent(createOnDismissedIntent(context))
    ;

    return builder;
}

and finally in the same NotificationManager is the perform function:

public void performNotifyCall(Intent intent) {
    String  action  = intent.getAction();
    boolean success = false;

    if(action.equals(ACTION_DELETE)) {
        success = delete(...);
    }

    if(action.equals(ACTION_SHOW)) {
        success = showDetails(...);
    }

    if(action.equals("ACTION_NOTIFY_DELETED")) {
        success = true;
    }


    if(success == false){
        return;
    }

    //some cleaning stuff
}
Lyndy answered 2/11, 2017 at 12:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.