Android: как отличить УДАЛИТЬ все события из панели уведомлений от действия пользователя

Согласно спецификации, .setDeleteIntent(pendingIntent) связано с обоими действиями (УДАЛИТЬ все события из панели уведомлений и действия пользователя, такие как смахивание).

Мои требования заключаются в том, что когда пользователь касается уведомления, которое появляется на панели уведомлений, он должен быть перенаправлен на страницу NotificationsList.class. Это делается с помощью моего pendingInent:

PendingIntent sendPendingIntent = PendingIntent.getActivity(context, reminderId, new Intent(context, NotificationsList.class), PendingIntent.FLAG_UPDATE_CURRENT);

Однако при нажатии кнопки ОЧИСТИТЬ пользователь не должен вообще переходить к приложению. С .setDeleteIntent(pendingIndent) я не могу выполнить 2-е требование. Пользователь по-прежнему переходит к NotificationsList.class.

Есть ли способ программно отличить CLEAR все события уведомлений, запущенные с помощью кнопки CLEAR, от действий пользователя, таких как касание или пролистывание определенного уведомления на панели уведомлений?


person goseib    schedule 29.08.2016    source источник
comment
Вы нашли ответ на свой вопрос? Вам нужна еще помощь? Пожалуйста, дайте мне знать, если вы это сделаете!   -  person bendaf    schedule 15.09.2016
comment
Тебе нужна еще помощь, братан? Почему вы не принимаете никаких ответов?   -  person bendaf    schedule 18.10.2016
comment
Пожалуйста, если вы найдете ответ на свой вопрос, примите один из приведенных ниже или измените свой вопрос, чтобы я мог помочь вам еще больше!   -  person bendaf    schedule 03.02.2017


Ответы (4)


То, что вы описываете, очень тупое поведение. Вам нужно только установить ожидающее намерение для вашего уведомления, и при нажатии на него будет выполнено поддерживающее его намерение.

Если ваш код возвращает пользователя в приложение, когда уведомление очищается, то у вас уже есть проблема с вашим дизайном. Если пользователь очищает ваше уведомление, вы НЕ должны пытаться вернуться к нему. Следовательно, setDeleteIntent() НЕ ДОЛЖЕН ассоциироваться с началом какой-либо деятельности.

Обратите внимание, что намерение, которое поддерживается, когда вы щелкаете уведомление (setContentIntent()) и очищаете (setDeleteIntent()) уведомление, в основном представляет собой два PendingIntent, они не должны быть одинаковыми, что и описывает ваша проблема.

person JoxTraex    schedule 02.09.2016

Вы не можете различить эти два события. Как сказано в документации:

Уведомления остаются видимыми до тех пор, пока не произойдет одно из следующих событий:

  • Пользователь отклоняет уведомление либо индивидуально, либо с помощью «Очистить все» (если уведомление можно очистить).
  • Пользователь щелкает уведомление, и вы вызвали setAutoCancel() при создании уведомления.
  • Вы вызываете cancel() для определенного идентификатора уведомления. Этот метод также удаляет текущие уведомления.
  • Вы вызываете cancelAll(), который удаляет все уведомления, которые вы ранее отправили.

Таким образом, программист видит в основном три разных события:

  • Вы отклоняете уведомление
  • Пользователь нажимает на уведомление
  • Пользователь закрывает уведомление (пролистнув или очистив его)

Первое событие запускается вами путем вызова cancelAll() или cancel().

Вы можете справиться со вторым лайком (что вы хотите сделать, я думаю):

NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
        //....
        .setContentIntent(sendPendingIntent);

И вы можете обработать третье событие, например (как вы описали выше):

builder.setDeleteIntent(pendingIndent)

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

Надеюсь, я смог помочь.

person bendaf    schedule 07.09.2016

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

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

Таким образом, ваша проблема должна быть решена путем изменения одного слова в требованиях: touch --> click.

person x-code    schedule 07.09.2016

Я погуглил deleteIntent, чтобы найти информацию о проблеме, которая привела меня сюда.

Английский мой второй язык. Заранее извините за неправильное употребление слов. Я новичок в Android, просто проголосуйте за ответ, если он отстой :)

Что касается вашего последнего вопроса, как сказали @x-code и @bendaf, невозможно отличить прокрутку от очистки.

Я следую codelabs об уведомлениях и столкнулся с тем же вопросом (описание в заголовке). Поэтому я решил предложить более подробную информацию о том, как использовать .setDeleteIntent в вашем случае. Может быть, вы сделали это.

В вашем случае обернутое намерение предназначено для запуска действия, поэтому сделайте pendingIntent.

PendingIntent sendPendingIntent = PendingIntent.getActivity(context, reminderId, new Intent(context, NotificationsList.class), PendingIntent.FLAG_UPDATE_CURRENT);

Но для выполнения трансляции, например. делая некоторые вещи, когда уведомление очищается, используйте:

PendingIntent pendingIntent = PendingIntent.getBroadcast(context, NOTIFICATION_ID, new Intent(yourCustomActionString), PendingIntent.FLAG_UPDATE_CURRENT);

builder.setDeleteIntent(pendingIntent); // the pendingIntent will be sent when the notification is cleared

Затем нам нужно, чтобы пользовательский широковещательный приемник получил это пользовательское действие, содержащееся в объекте Intent, в вашем случае это действие относится к очистке:

// Inside onCreate, register the broadcast receiver;
registerReceiver(new MyReceiver(), new IntentFilter(yourCustomActionString));
.
.
// Create an inner class
public class MyReceiver extends BroadcastReceiver {
    public NotificationReceiver() {}
    @Override
    public void onReceive(Context context, Intent intent) {
        // code inside will be executed when pendingIntent is sent
        Log("taG", "Notification is cleared"); // a message will be logged if the notification is cleared
        // for more than one action, using switch...case to decide
    }
}
person kiz    schedule 22.11.2019