Использование root для очистки уведомлений строки состояния

В настоящее время я работаю над приложением, использующим службу доступности для обработки уведомлений. Что особенно раздражает: сторонним приложениям не удалять уведомления о статусной строке, кроме запуска намерения, связанного с уведомлением (и запуска приложения).

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

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

Мне было интересно, есть ли способ взаимодействовать с уведомлениями о статусной строке с использованием какой-либо базы данных или с помощью простого вызова SU.

Ответ 1

ОБНОВЛЕНИЕ. См. рабочий вариант ниже

Весь этот материал обрабатывается службой NotificationManagerService (см. здесь https://github.com/android/platform_frameworks_base/blob/master/services/java/com/android/server/NotificationManagerService.java). Я думаю, в частности, вас будет интересовать метод void cancelAll (int userId). Когда вы нажимаете на экране состояния, что метод, который фактически вызывается (с параметром ActivityManager.getCurrentUser() в качестве параметра).

Вы можете попытаться получить экземпляр его, вызвав NotificationManager.getService через отражение (см. скрытый метод getService() в NotificationManager http://androidxref.com/4.2.2_r1/xref/frameworks/base/core/java/android/app/NotificationManager.java), а затем попробуйте каким-то образом вызвать cancelAll в возвращаемой службе (например, через отражение снова).

UPDATE

Я нашел более простой способ очистки уведомлений через службу состояния. Следующий код должен работать:

IBinder b = (IBinder) Class.forName("android.os.ServiceManager").getMethod("getService", new Class[] {
    String.class
}).invoke(null, new Object[] {
    "statusbar"
});

Object iFace = Class.forName("com.android.internal.statusbar.IStatusBarService$Stub").getDeclaredMethod("asInterface", new Class[] {
    IBinder.class
}).invoke(null, new Object[] {
    b
});

iFace.getClass().getMethod("onClearAllNotifications", new Class[0]).invoke(iFace, (Object[]) null);

Это вызовет исключение SecurityException, если вы не используете его как root, но успешно удаляет уведомления, если у вас есть права root

Ответ 2

Вы можете очистить все уведомления, вызвав

service call notification 1

в оболочке с правами root