スワイプでキャッチしてイベントを終了します


85

サービスが終了したとき(成功または失敗)にユーザーに警告するためにAndroid通知を使​​用していますが、プロセスが完了したらローカルファイルを削除したいと思います。

私の問題は、失敗した場合に、ユーザーに「再試行」オプションを許可したいということです。彼が再試行せずに通知を閉じることを選択した場合、プロセス目的で保存されたローカルファイル(画像...)を削除したいと思います。

通知のスワイプして閉じるイベントをキャッチする方法はありますか?

回答:


144

DeleteIntent:DeleteIntentはPendingIntentオブジェクトであり、通知に関連付けることができ、通知が削除されると発生します。

  • ユーザー固有のアクション
  • ユーザーすべての通知を削除します。

保留中のインテントをブロードキャストレシーバーに設定してから、必要なアクションを実行できます。

  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
         }

  }

8
これは遅いです。builder.setAutoCancel(true);ユーザーが通知をクリックしてキャンセルされたときに発生した通知に対して同様のアプローチがあるかどうか疑問に思っていました。削除-インテントはトリガーされません
devanshu_kaushik 2015年

1
@dev_androidチェックアウトdeveloper.android.com/reference/android/app/...
Mr.Me

ええ、正常に動作していますが、Oreo以上のAPIでは動作しません。オレオのために私を助けてください
ピーター

@Peter OreoとOboveで機能させるには、次のコード行を追加する必要があります。Notificationnote = builder.build(); note.flags | = Notification.FLAG_AUTO_CANCEL;
Dimas Mendes

86

完全にフラッシュされた回答(回答をくれたMe氏に感謝します):

1)スワイプして閉じるイベントを処理するレシーバーを作成します。

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)保留中のインテントの一意のIDを使用して保留中のインテントを作成します(ここでは通知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/...
アレクセエフバレリー

これは私にとってはうまくいきますが、通知をクリックしてもイベントを呼び出すことはできません。クリックイベントを聞くにはどうすればよいですか?
Allen Vork 2016年

あなたが使用している場合、ドキュメントによると、setAutoCancel(true)、通知は、削除の意図[ブロードキャストもクリックされたときにキャンセルされ、developer.android.com/reference/android/support/v4/app/...
スヴェン

これは、パラメーターの受け渡しを除いて機能しますが、エクストラが設定されている場合でも、intent.getExtras()は常にnullを返します。それが機能するためには、次のようにアクションを設定する必要があります:resultIntent.setAction(unique_action);
lxknvlk 2017

0

別のアイデア:

通常、通知を作成する場合は、そのうちの1つ、2つ、または3つのアクションも必要です。「NotifyManager」を作成しました。これにより、必要なすべての通知が作成され、すべてのインテント呼び出しも受信されます。だから私はすべてのアクションを管理することができ、また1つの場所で却下イベントをキャッチすることができます。

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

そして、私がこのように削除インテントを設定するために使用すること(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
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.