Подтвердить что ты не робот

Как узнать, включены ли уведомления или нет для приложения в android?

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

appOpsClass = Class.forName(AppOpsManager.class.getName());
Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE, String.class);
Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION);
int value = (int)opPostNotificationValue.get(Integer.class);
return ((int)checkOpNoThrowMethod.invoke(mAppOps,value, appUID, appPackage) == AppOpsManager.MODE_ALLOWED);

Я получил следующее исключение:

Вызвано: java.lang.SecurityException: uid 10062 не имеет  android.permission.UPDATE_APP_OPS_STATS. W/System.err: at android.os.Parcel.readException(Parcel.java:1683) W/System.err: at android.os.Parcel.readException(Parcel.java:1636) W/System.err: at com.android.internal.app.IAppOpsService $Stub $Proxy.checkOperation(IAppOpsService.java:343)

Я включил

<uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS"/>

Тем не менее, я получаю ту же ошибку. С помощью какого apis можно получить значение, заблокировано или нет.

С помощью какого apis я могу получить эти значения?

4b9b3361

Ответ 1

Я боюсь, что это возможно только для текущего приложения. Вот почему public API NotificationManager имеет функцию areNotificationsEnabled() для текущего пакета.

Изучая исходный код Android, я нашел AppNotificationSettings - настройки уведомлений приложения. Первый переключатель указывает, заблокированы ли уведомления или нет. Слушатель коммутатора здесь, который указывает на NotificationBackend. В этом классе существует метод:

public boolean getNotificationsBanned(String pkg, int uid)

который использует INotificationManager (класс, сгенерированный из файла .aidl во время компиляции) и его метод:

boolean areNotificationsEnabledForPackage(String pkg, int uid);

Это частный API для Android, который нельзя просто вызвать. Поэтому я пробовал размышлять:

try {
    NotificationManager mNotificationManager = null;
    Class<?> c = Class.forName("android.app.NotificationManager");
    Method method = c.getMethod("getService");
    Object obj = method.invoke(mNotificationManager);
    Class<?> clazz = Class.forName("android.app.INotificationManager$Stub$Proxy");
    Method areNotificationsEnabledForPackage = clazz.getMethod("areNotificationsEnabledForPackage", String.class, int.class);
    boolean blocked = (boolean) areNotificationsEnabledForPackage.invoke(obj, getPackageName(), android.os.Process.myUid());
    Log.d(MainActivity.class.getSimpleName(), String.valueOf(blocked));
} catch (Exception e) {
    e.printStackTrace();
}

Однако, как вы можете видеть, вы должны сначала создать NotificationManager. К сожалению, этот класс создан для пакета. Поэтому приведенный выше код будет использоваться только для:

boolean blocked = (boolean) areNotificationsEnabledForPackage.invoke(obj, getPackageName(), android.os.Process.myUid());

однако это не сработает:

//InvocationTargetException will be thrown.
boolean blocked = (boolean) areNotificationsEnabledForPackage.invoke(obj, "com.android.camera", 10040);

Вывод:

Невозможно выполнить.