【问题标题】:catch on swipe to dismiss event抓住滑动以关闭事件
【发布时间】:2013-01-18 06:00:18
【问题描述】:

一旦服务完成(成功或失败),我正在使用 android 通知提醒用户,并且我想在该过程完成后删除本地文件。

我的问题是,如果发生故障 - 我想让用户有一个“重试”选项。如果他选择不重试并关闭通知,我想删除为处理目的而保存的本地文件(图像...)。

有没有办法捕捉通知的滑动关闭事件?

【问题讨论】:

    标签: android service notifications swipe temporary-files


    【解决方案1】:

    删除意图: DeleteIntent 是一个 PendingIntent 对象,可以与通知相关联,并在通知被删除时触发,ether by :

    • 用户特定操作
    • 用户删除所有通知。

    您可以将 Pending Intent 设置为广播接收器,然后执行您想要的任何操作。

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

    【讨论】:

    • 来晚了。我只是想知道是否有类似的通知方法有builder.setAutoCancel(true);,因为当用户单击通知并取消通知时,不会触发删除意图
    • @Peter 为了让它在 Oreo 和 Obve 中工作,你需要添加这行代码: Notification note = builder.build(); note.flags |= Notification.FLAG_AUTO_CANCEL;
    【解决方案2】:

    一个完整的答案(感谢我先生的回答):

    1) 创建一个接收器来处理 swipe-to-dismiss 事件:

    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) 在清单中添加一个条目:

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

    3) 为待处理的 Intent 使用唯一的 id 创建待处理的 Intent(此处使用通知 ID),因为没有这个,相同的额外内容将被重复用于每个解除事件:

    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) 构建您的通知:

    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);
    

    【讨论】:

    • 对我不起作用,总是导致错误“无法实例化接收器....没有零参数构造函数”。仅在我实施了另一个类似的解决方案但注册广播接收器后才解决:stackoverflow.com/questions/13028122/…
    • 这对我有用。但是当您单击通知时无法调用该事件。我该如何收听单击事件?
    • 根据文档,如果你使用setAutoCancel(true),那么点击时通知将被取消并广播删除意图[developer.android.com/reference/android/support/v4/app/…
    • 这行得通,除了参数传递,intent.getExtras() 总是返回 null,即使设置了 extras。为了让它工作,你必须像这样设置动作:resultIntent.setAction(unique_action);
    【解决方案3】:

    另一个想法:

    如果您正常创建通知,您还需要其中的一、二或三项操作。我创建了一个“NotifyManager”,它创建了我需要的所有通知并接收所有 Intent 调用。 所以我可以管理所有的动作,也可以在一个地方捕捉解雇事件。

    public class NotifyPerformService extends IntentService {
    
    @Inject NotificationManager notificationManager;
    
    public NotifyPerformService() {
        super("NotifyService");
        ...//some Dagger stuff
    }
    
    @Override
    public void onHandleIntent(Intent intent) {
        notificationManager.performNotifyCall(intent);
    }
    

    要创建 deleteIntent 使用这个(在 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;
    }
    

    我用来设置删除 Intent 像这样(在 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;
    }
    

    最后在同一个 NotificationManager 中是 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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-29
      • 2017-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多