it-swarm.com.ru

Как отменить уведомление после нажатия на действие

Начиная с уровня API 16 (Jelly bean), есть возможность добавлять действия в уведомление с

builder.addAction(iconId, title, intent);

Но когда я добавляю действие к уведомлению и действие нажимается, уведомление не будет отклонено. При нажатии на уведомление, оно может быть отклонено с

notification.flags = Notification.FLAG_AUTO_CANCEL;

или же

builder.setAutoCancel(true);

Но очевидно, что это не имеет ничего общего с действиями, связанными с уведомлением.

Есть намеки? Или это еще не часть API? Я не нашел ничего.

125
endowzoner

Когда вы вызвали notify в менеджере уведомлений, вы дали ему идентификатор - это уникальный идентификатор, который вы можете использовать для доступа к нему позже (это из менеджера уведомлений:

notify(int id, Notification notification)

Чтобы отменить, вы бы позвонили:

cancel(int id)

с тем же идентификатором. Итак, в основном, вам нужно отслеживать идентификатор или, возможно, поместить идентификатор в Bundle, который вы добавляете в Intent внутри PendingIntent?

139
Kaediil

Обнаружил, что это проблема при использовании уведомления Lollipop Heads Up Display. Смотрите рекомендации по дизайну . Вот полный (ish) код для реализации.

До сих пор кнопка "Отклонить" была менее важна, но теперь она более важна для вас.

heads up notification

Построение уведомления

int notificationId = new Random().nextInt(); // just use a counter in some util class...
PendingIntent dismissIntent = NotificationActivity.getDismissIntent(notificationId, context);

NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setPriority(NotificationCompat.PRIORITY_MAX) //HIGH, MAX, FULL_SCREEN and setDefaults(Notification.DEFAULT_ALL) will make it a Heads Up Display Style
        .setDefaults(Notification.DEFAULT_ALL) // also requires VIBRATE permission
        .setSmallIcon(R.drawable.ic_action_refresh) // Required!
        .setContentTitle("Message from test")
        .setContentText("message")
        .setAutoCancel(true)
        .addAction(R.drawable.ic_action_cancel, "Dismiss", dismissIntent)
        .addAction(R.drawable.ic_action_boom, "Action!", someOtherPendingIntent);

// Gets an instance of the NotificationManager service
NotificationManager notifyMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

// Builds the notification and issues it.
notifyMgr.notify(notificationId, builder.build());

NotificationActivity

public class NotificationActivity extends Activity {

    public static final String NOTIFICATION_ID = "NOTIFICATION_ID";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.cancel(getIntent().getIntExtra(NOTIFICATION_ID, -1));
        finish(); // since finish() is called in onCreate(), onDestroy() will be called immediately
    }

    public static PendingIntent getDismissIntent(int notificationId, Context context) {
        Intent intent = new Intent(context, NotificationActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        intent.putExtra(NOTIFICATION_ID, notificationId);
        PendingIntent dismissIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        return dismissIntent;
    }

}

AndroidManifest.xml (атрибуты, необходимые для предотвращения фокусировки SystemUI на заднем стеке)

<activity
    Android:name=".NotificationActivity"
    Android:taskAffinity=""
    Android:excludeFromRecents="true">
</activity>
60
aaronvargas

Я обнаружил, что когда вы используете кнопки действий в расширенных уведомлениях, вы должны писать дополнительный код, и вы более ограничены.

Вы должны вручную отменить свое уведомление, когда пользователь нажимает кнопку действия. Уведомление отменяется только автоматически для действия по умолчанию.

Также, если вы запускаете широковещательный приемник с кнопки, ящик уведомлений не закрывается.

В итоге я создал новую функцию NotificationActivity для решения этих проблем. Это посредническое действие без какого-либо пользовательского интерфейса отменяет уведомление, а затем запускает действие, которое я действительно хотел начать с уведомления.

Я разместил пример кода в соответствующем сообщении Нажатие Android Действия уведомления не закрывает панель уведомлений .

15
Vicki

В моем мнении использование BroadcastReceiver является более чистым способом отменить уведомление:

В AndroidManifest.xml:

<receiver 
    Android:name=.NotificationCancelReceiver" >
    <intent-filter Android:priority="999" >
         <action Android:name="com.example.cancel" />
    </intent-filter>
</receiver>

В Java файле:

Intent cancel = new Intent("com.example.cancel");
PendingIntent cancelP = PendingIntent.getBroadcast(context, 0, cancel, PendingIntent.FLAG_CANCEL_CURRENT);

NotificationCompat.Action actions[] = new NotificationCompat.Action[1];


NotificationCancelReceiver

public class NotificationCancelReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //Cancel your ongoing Notification
    };
}
5
Himanshu Khandelwal

Вы всегда можете cancel()Notification из того, что вызывается действием (например, в onCreate() действия, связанного с PendingIntent, который вы предоставляете addAction()).

5
CommonsWare

В новых API не забудьте про TAG:

notify(String tag, int id, Notification notification)

и соответственно

cancel(String tag, int id) 

вместо:

cancel(int id)

https://developer.Android.com/reference/Android/app/NotificationManager

2
Malachiasz

Просто поместите эту строку:

 builder.setAutoCancel(true);

И полный код:

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    builder.setSmallIcon(Android.R.drawable.ic_dialog_alert);
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.co.in/"));
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
    builder.setContentIntent(pendingIntent);
    builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.misti_ic));
    builder.setContentTitle("Notifications Title");
    builder.setContentText("Your notification content here.");
    builder.setSubText("Tap to view the website.");
    Toast.makeText(getApplicationContext(), "The notification has been created!!", Toast.LENGTH_LONG).show();

    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    builder.setAutoCancel(true);
    // Will display the notification in the notification bar
    notificationManager.notify(1, builder.build());
1
Hanisha