проблемы с очисткой уведомлений в Android [duplicate]

Если вы хотите разницу рекурсивно, я написал пакет для python: https://github.com/seperman/deepdiff

Установка

Установить из PyPi:

pip install deepdiff

Пример использования

Импорт

>>> from deepdiff import DeepDiff
>>> from pprint import pprint
>>> from __future__ import print_function # In case running on Python 2

Тот же объект возвращает пустой

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = t1
>>> print(DeepDiff(t1, t2))
{}

Изменен тип элемента

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:"2", 3:3}
>>> pprint(DeepDiff(t1, t2), indent=2)
{ 'type_changes': { 'root[2]': { 'newtype': ,
                                 'newvalue': '2',
                                 'oldtype': ,
                                 'oldvalue': 2}}}

Значение элемента изменилось

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:4, 3:3}
>>> pprint(DeepDiff(t1, t2), indent=2)
{'values_changed': {'root[2]': {'newvalue': 4, 'oldvalue': 2}}}

Добавлен элемент и / или удален

>>> t1 = {1:1, 2:2, 3:3, 4:4}
>>> t2 = {1:1, 2:4, 3:3, 5:5, 6:6}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff)
{'dic_item_added': ['root[5]', 'root[6]'],
 'dic_item_removed': ['root[4]'],
 'values_changed': {'root[2]': {'newvalue': 4, 'oldvalue': 2}}}

Разность строк

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world"}}
>>> t2 = {1:1, 2:4, 3:3, 4:{"a":"hello", "b":"world!"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'values_changed': { 'root[2]': {'newvalue': 4, 'oldvalue': 2},
                      "root[4]['b']": { 'newvalue': 'world!',
                                        'oldvalue': 'world'}}}

Разница в строках 2

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world!\nGoodbye!\n1\n2\nEnd"}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world\n1\n2\nEnd"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'values_changed': { "root[4]['b']": { 'diff': '--- \n'
                                                '+++ \n'
                                                '@@ -1,5 +1,4 @@\n'
                                                '-world!\n'
                                                '-Goodbye!\n'
                                                '+world\n'
                                                ' 1\n'
                                                ' 2\n'
                                                ' End',
                                        'newvalue': 'world\n1\n2\nEnd',
                                        'oldvalue': 'world!\n'
                                                    'Goodbye!\n'
                                                    '1\n'
                                                    '2\n'
                                                    'End'}}}

>>> 
>>> print (ddiff['values_changed']["root[4]['b']"]["diff"])
--- 
+++ 
@@ -1,5 +1,4 @@
-world!
-Goodbye!
+world
 1
 2
 End

Изменение типа

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world\n\n\nEnd"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'type_changes': { "root[4]['b']": { 'newtype': ,
                                      'newvalue': 'world\n\n\nEnd',
                                      'oldtype': ,
                                      'oldvalue': [1, 2, 3]}}}

Разница в списке

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3, 4]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{'iterable_item_removed': {"root[4]['b'][2]": 3, "root[4]['b'][3]": 4}}

Переменная списка 2 :

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 3, 2, 3]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'iterable_item_added': {"root[4]['b'][3]": 3},
  'values_changed': { "root[4]['b'][1]": {'newvalue': 3, 'oldvalue': 2},
                      "root[4]['b'][2]": {'newvalue': 2, 'oldvalue': 3}}}

Разница в списке игнорирует порядок или дубликаты: (с теми же словарями, что и выше)

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 3, 2, 3]}}
>>> ddiff = DeepDiff(t1, t2, ignore_order=True)
>>> print (ddiff)
{}

Список, содержащий словарь:

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, {1:1, 2:2}]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, {1:3}]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'dic_item_removed': ["root[4]['b'][2][2]"],
  'values_changed': {"root[4]['b'][2][1]": {'newvalue': 3, 'oldvalue': 1}}}

Наборы:

>>> t1 = {1, 2, 8}
>>> t2 = {1, 2, 3, 5}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (DeepDiff(t1, t2))
{'set_item_added': ['root[3]', 'root[5]'], 'set_item_removed': ['root[8]']}

Именованные кортежи:

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> t1 = Point(x=11, y=22)
>>> t2 = Point(x=11, y=23)
>>> pprint (DeepDiff(t1, t2))
{'values_changed': {'root.y': {'newvalue': 23, 'oldvalue': 22}}}

Пользовательские объекты:

>>> class ClassA(object):
...     a = 1
...     def __init__(self, b):
...         self.b = b
... 
>>> t1 = ClassA(1)
>>> t2 = ClassA(2)
>>> 
>>> pprint(DeepDiff(t1, t2))
{'values_changed': {'root.b': {'newvalue': 2, 'oldvalue': 1}}}

Добавлен атрибут объекта:

>>> t2.c = "new attribute"
>>> pprint(DeepDiff(t1, t2))
{'attribute_added': ['root.c'],
 'values_changed': {'root.b': {'newvalue': 2, 'oldvalue': 1}}}

83
задан Irfan DANISH 8 November 2013 в 08:58
поделиться

12 ответов

Используйте следующий код для отмены уведомления:

NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(NOTIFICATION_ID);

В этом коде всегда используется один и тот же идентификатор, используемый для уведомлений. Если у вас есть разные уведомления, которые необходимо отменить, вам нужно сохранить идентификаторы, которые вы использовали для создания Уведомления.

205
ответ дан Janusz 22 August 2018 в 11:31
поделиться
  • 1
    Я не знаю, почему это больше не поддерживается и выбрано в качестве ответа. Это было решение, которое я искал. Благодаря! – loeschg 30 January 2013 в 01:48
  • 2
    Каким должен быть идентификатор уведомления? – Deepak 23 November 2015 в 08:50
  • 3
    Это действительно работает. Но как только я отменяю уведомление, все последующие уведомления не отображают текст сообщения уведомления (который я установил с помощью setContentText), хотя я установил приоритет на 2. Любые предложения? – Iqbal 26 February 2016 в 13:10
  • 4
    Не работает, если флаг уведомления установлен как Notification.FLAG_NO_CLEAR – Anand Savjani 2 December 2016 в 05:28
  • 5
    для всех, и если вы не знаете, какой id, if (notificationManager! = null) {notificationManager.cancelAll (); } – mehmet 25 December 2017 в 10:31

На самом деле, как ответ, прежде чем начинать с уровня API 18, вы можете отменить уведомления, опубликованные другими приложениями, чем ваши собственные, используя NotificationListenerService, но этот подход больше не будет работать на Lollipop, вот способ удалить уведомления, охватывающие также Lillipop API.

if (Build.VERSION.SDK_INT < 21) {
    cancelNotification(sbn.getPackageName(), sbn.getTag(), sbn.getId());
}
else {
    cancelNotification(sbn.getKey());
}
1
ответ дан Alejandro Casanova 22 August 2018 в 11:31
поделиться

Все уведомления (даже другие уведомления о приложениях) можно удалить, прослушивая «NotificationListenerService», как указано в NotificationListenerService Implementation

. В службе вы должны вызвать cancelAllNotifications().

Услуга должна быть включена для вашего приложения через:

'Apps & amp; уведомления »->« Доступ к специальному приложению »->« Доступ к уведомлениям ».

0
ответ дан CertainPerformance 22 August 2018 в 11:31
поделиться

От: http://developer.android.com/guide/topics/ui/notifiers/notifications.html

Чтобы очистить уведомление в строке состояния, когда пользователь выбирает его из окна «Уведомления», добавляет флаг «FLAG_AUTO_CANCEL» к вашему объекту «Уведомление». Вы также можете очистить его вручную с помощью отмены (int), передав ему идентификатор уведомления или очистить все ваши уведомления с помощью cancelAll ().

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

40
ответ дан Chuck C. 22 August 2018 в 11:31
поделиться
  • 1
    Это не будет отменять уведомление программно. – Janusz 2 November 2012 в 12:21
  • 2
    не знаю, о чем говорит Януш, но отмените (id) и cancelAll (), безусловно, работайте – Andrew G 11 April 2013 в 18:41
  • 3
    Я думаю, Януш и только прочитал первое предложение цитируемого текста :) – k2col 31 March 2014 в 21:37
   String ns = Context.NOTIFICATION_SERVICE;
  NotificationManager Nmang = (NotificationManager) getApplicationContext()
                                                     .getSystemService(ns);
  Nmang .cancel(getIntent().getExtras().getInt("notificationID"));

для получения дополнительной информации нажмите здесь http://androiddhina.blogspot.in/2015/01/how-to-clear-notification-in-android.html

1
ответ дан Dhina k 22 August 2018 в 11:31
поделиться

Если вы генерируете уведомление из службы, запущенной на переднем плане, используя

startForeground(NOTIFICATION_ID, notificationBuilder.build());

, то выдача

notificationManager.cancel(NOTIFICATION_ID);

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

stopForeground( true );

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

stopForeground( false );
notificationManager.cancel(NOTIFICATION_ID);
0
ответ дан Ian Gough 22 August 2018 в 11:31
поделиться

Начиная с уровня API 18 (Jellybean MR2) вы можете отменить Уведомления, отличные от вашего, через NotificationListenerService.

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class MyNotificationListenerService extends NotificationListenerService {...}

...

private void clearNotificationExample(StatusBarNotification sbn) {
    myNotificationListenerService.cancelNotification(sbn.getPackageName(), sbn.getTag(), sbn.getId());
}
8
ответ дан Jim Vitek 22 August 2018 в 11:31
поделиться
  • 1
    Это действительно работало для меня. Спасибо. – user1406716 9 September 2014 в 08:50
 Notification mNotification = new Notification.Builder(this)

                .setContentTitle("A message from: " + fromUser)
                .setContentText(msg)
                .setAutoCancel(true)
                .setSmallIcon(R.drawable.app_icon)
                .setContentIntent(pIntent)
                .build();

.setAutoCancel (true)

, когда вы нажимаете на уведомление, открываете соответствующую активность и удаляете уведомление с панели уведомлений

3
ответ дан Neeraj Singh 22 August 2018 в 11:31
поделиться

Поскольку никто не отправил код ответа на этот вопрос:

notification.flags = Notification.FLAG_AUTO_CANCEL;

.. и если у вас уже есть флаги, вы можете ИЛИ FLAG_AUTO_CANCEL следующим образом:

notification.flags = Notification.FLAG_INSISTENT | Notification.FLAG_AUTO_CANCEL;
32
ответ дан NPike 22 August 2018 в 11:31
поделиться
  • 1
    Это лучше: notifcation.flags |= Notification.FLAG_AUTO_CANCEL; – Sebastian Nowak 8 August 2012 в 11:47
  • 2
    Может ли кто-нибудь объяснить, почему так лучше? – Prof 14 February 2017 в 00:11
  • 3
    @Prof Это меньше кода для той же цели и не влияет на производительность. – Denny 18 February 2017 в 16:06
  • 4
    @Denny. Предполагается, что первый флаг уведомления определен выше, поэтому вместо двух строк вместо двух строк – Prof 18 February 2017 в 17:09

Попробуйте использовать метод по умолчанию, указанный в NotificationManager .

NotificationManager.cancelAll(), чтобы удалить все уведомления. NotificationManager.cancel(notificationId), чтобы удалить определенное уведомление.

11
ответ дан Rohit Suthar 22 August 2018 в 11:31
поделиться
  • 1
    В случае, если кто-то застрял в NotificationManager, не имея метода cancel, метод cancel не является статичным, поэтому вам нужен экземпляр NotificationManager, подобный этому: NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); Затем вы можете вызвать notificationManager.cancel(notificationId);, как Rohit Suthar упоминается в его ответе. notificationId - это просто идентификатор, который вы передали в notificationManager.notify(notificationId, mNotification) – Mira_Cole 13 March 2018 в 14:59

Если вы используете NotificationCompat.Builder (часть android.support.v4), просто вызовите его метод объекта setAutoCancel

NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setAutoCancel(true);

Некоторые ребята сообщают, что setAutoCancel() не работает их, так что вы также можете попробовать этот путь

builder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;

Обратите внимание, что метод getNotification() устарел !!!

3
ответ дан sandalone 22 August 2018 в 11:31
поделиться
  • 1
    Вопрос задавался вопросом, как его программно очистить. setAutoCancel () очищает его, когда пользователь нажимает на уведомление. [Д0] developer.android.com/reference/android/support/v4/app/… – S Fitz 5 August 2015 в 07:32
  • 2
    @SFitz Непонятно, из чего он хочет. Я понял, что он хочет очистить уведомление, когда пользователь нажимает на него. – sandalone 5 August 2015 в 10:46
    // Get a notification builder that's compatible with platform versions
    // >= 4
    NotificationCompat.Builder builder = new NotificationCompat.Builder(
            this);
    builder.setSound(soundUri);
    builder.setAutoCancel(true);

это работает, если вы используете построитель уведомлений ...

0
ответ дан user2962552 22 August 2018 в 11:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: