deslize para dispensar o evento

85

Estou usando uma notificação do Android para alertar o usuário quando um serviço é concluído (sucesso ou falha) e desejo excluir os arquivos locais quando o processo for concluído.

Meu problema é que, em caso de falha - quero deixar ao usuário a opção de "repetir". e se ele escolher não tentar novamente e descartar a notificação, desejo excluir os arquivos locais salvos para fins de processo (imagens ...).

Existe uma maneira de capturar o evento deslizar para dispensar da notificação?

Dror Fichman
fonte

Respostas:

145

DeleteIntent : DeleteIntent é um objeto PendingIntent que pode ser associado a uma notificação e é disparado quando a notificação é excluída, por:

  • Ação específica do usuário
  • Usuário Exclua todas as notificações.

Você pode definir a intenção pendente para um receptor de transmissão e, em seguida, executar qualquer ação que desejar.

  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
         }

  }
Mr.Me
fonte
8
Esta tarde. Eu estava pensando se existe uma abordagem semelhante para notificações que ocorre builder.setAutoCancel(true);porque quando um usuário clica na notificação e ela é cancelada, delete-Intent não é acionado
devanshu_kaushik
1
@dev_android checkout developer.android.com/reference/android/app/…
Mr.Me
@Peter Para fazê-lo funcionar no Oreo e no Obove, você precisa adicionar esta linha de código: Notification note = builder.build (); note.flags | = Notificação.FLAG_AUTO_CANCEL;
Dimas Mendes
86

Uma resposta totalmente corada (com agradecimentos ao Sr. Me pela resposta):

1) Crie um receptor para lidar com o evento de deslizar para dispensar:

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) Adicione uma entrada ao seu manifesto:

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

3) Crie a intent pendente usando um id exclusivo para a intent pendente (o id de notificação é usado aqui), pois sem isso os mesmos extras serão reutilizados para cada evento de dispensa:

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) Crie sua notificação:

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
fonte
Não funcionou para mim, sempre resultava com o erro "Não foi possível instanciar o receptor .... não tem nenhum construtor de argumento". Resolvido apenas depois de implementar outra solução semelhante, mas com o registro do receptor de transmissão: stackoverflow.com/questions/13028122/…
Alexeev Valeriy
Isso funciona para mim. Mas o evento não pode ser invocado quando você clica na notificação. Como posso ouvir o evento de clique?
Allen Vork de
De acordo com os documentos, se você usar setAutoCancel(true), a notificação será cancelada quando clicada e também transmitirá a intenção de exclusão [ developer.android.com/reference/android/support/v4/app/…
sven
Isso funciona, exceto a passagem de parâmetro, intent.getExtras () sempre retorna nulo, mesmo se extras forem definidos. Para que funcione, você deve definir a ação da seguinte forma: resultIntent.setAction (unique_action);
lxknvlk
0

Outra ideia:

se você criar uma notificação normalmente, também precisará das ações um, dois ou 3 deles. Eu criei um "NotifyManager" que cria todas as notificações de que preciso e também recebe todas as chamadas de Intent. Assim, posso gerenciar todas as ações E também pegar o evento de dispensa em UM 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 criar o deleteIntent, use isto (no 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;
}

e O QUE eu uso para definir o intent de exclusão assim (no 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;
}

e finalmente no mesmo NotificationManager está a função de execução:

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
fonte