captura al deslizar para descartar el evento

85

Estoy usando una notificación de Android para alertar al usuario una vez que finaliza un servicio (éxito o fracaso), y quiero eliminar archivos locales una vez que finaliza el proceso.

Mi problema es que, en caso de falla, quiero permitirle al usuario una opción de "reintento". y si elige no volver a intentarlo y descartar la notificación, quiero eliminar los archivos locales guardados para el proceso (imágenes ...).

¿Hay alguna forma de detectar el evento de deslizar para descartar de la notificación?

Dror Fichman
fuente

Respuestas:

144

DeleteIntent : DeleteIntent es un objeto PendingIntent que se puede asociar con una notificación y se activa cuando se elimina la notificación, a través de:

  • Acción específica del usuario
  • Usuario Eliminar todas las notificaciones.

Puede establecer la intención pendiente en un receptor de transmisión y luego realizar cualquier acción que desee.

  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
         }

  }
Señor yo
fuente
8
Esto es tarde. Me preguntaba si existe un enfoque similar para las notificaciones que se debe a que builder.setAutoCancel(true);cuando un usuario hace clic en la notificación y se cancela, no se activa la
intención de eliminación
1
@dev_android checkout developer.android.com/reference/android/app/…
Mr.Me
Sí, funciona bien, pero no en Oreo ni en API superiores. Por favor, ayúdame para Oreo
Peter
@Peter Para que funcione en Oreo y Obove, debe agregar esta línea de código: Nota de notificación = builder.build (); note.flags | = Notificación.FLAG_AUTO_CANCEL;
Dimas Mendes
86

Una respuesta completamente enrojecida (con agradecimiento al Sr.Me por la respuesta):

1) Cree un receptor para manejar el evento de deslizar para descartar:

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) Agregue una entrada a su manifiesto:

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

3) Cree la intención pendiente usando una identificación única para la intención pendiente (la identificación de notificación se usa aquí) ya que sin esto, los mismos extras se reutilizarán para cada evento de despido:

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) Cree su notificación:

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);
Chris Knight
fuente
No funcionó para mí, siempre resultó con el error "No se puede crear una instancia del receptor ... no tiene un constructor de argumento cero". Resuelto solo después de haber implementado otra solución similar pero con el registro del receptor de transmisión: stackoverflow.com/questions/13028122/…
Alexeev Valeriy
Esto funciona para mí, pero el evento no se puede invocar cuando haces clic en la notificación. ¿Cómo puedo escuchar el evento de clic?
Allen Vork
De acuerdo con los documentos, si usa setAutoCancel(true), la notificación se cancelará cuando se haga clic y también se transmitirá la intención de eliminación [ developer.android.com/reference/android/support/v4/app/…
sven
Esto funciona, excepto el paso de parámetros, intent.getExtras () siempre devuelve nulo, incluso si se establecen extras. Para que funcione, debe establecer una acción como esta: resultIntent.setAction (unique_action);
lxknvlk
0

Otra idea:

si crea una notificación normalmente también necesita las acciones una, dos o 3 de ellas. He creado un "NotifyManager" que crea todas las notificaciones que necesito y también recibe todas las llamadas de intención. Entonces puedo administrar todas las acciones Y también capturar el evento de despedida en UN solo lugar.

public class NotifyPerformService extends IntentService {

@Inject NotificationManager notificationManager;

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

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

para crear el deleteIntent use esto (en el 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;
}

y que utilizo para configurar el intento de eliminación de esta manera (en el 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;
}

y finalmente en el mismo NotificationManager está la función perform:

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
}
HowardS
fuente