13

I've a ListView which has the list of installed applications and for each application, I need to know whether the notifications are enabled or not. Currently I'm using below code to know if the notifications are enabled:

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);

I got the following exception:

Caused by: java.lang.SecurityException: uid 10062 does not have 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)

I've included

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

Still I'm getting the same error. Using what apis can I get the value whether it is blocked or not

Using what apis can I get these values?

mmBs
  • 8,421
  • 6
  • 38
  • 46
Ashraf
  • 143
  • 1
  • 8
  • 1
    Which API version are you using to build the app and which android version are you testing your app on? I am asking this because for certain sensitive permissions in Android 6 and above, you need to get the permission from users on runtime. https://developer.android.com/training/permissions/requesting.html – Shobhit Puri Oct 07 '16 at 16:10
  • See if `NotificationManager.getNotificationPolicy()` does it for you. [Link](https://developer.android.com/reference/android/app/NotificationManager.html#getNotificationPolicy()) – sonictt1 Oct 07 '16 at 16:14

2 Answers2

9

I am afraid this is only possible for the current application. That is why the public API of NotificationManager has the function areNotificationsEnabled() for the current package.

When looking into android source code, I found AppNotificationSettings - application notification settings. The first switch indicates, whether notifications are blocked or not. The switch listener is here, which points to NotificationBackend. In this class, there is method:

public boolean getNotificationsBanned(String pkg, int uid)

which uses INotificationManager ( a class generated from .aidl file during compilation) and it's method:

boolean areNotificationsEnabledForPackage(String pkg, int uid);

This is Android private API, cannot be simply invoked. So I tried reflection:

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();
}

However, as you can see, you must first create NotificationManager. Sadly, this class is created for package. So the code above will for only for :

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

however this will not work :

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

Conclusion:

Cannot be done.

R. Zagórski
  • 20,020
  • 5
  • 65
  • 90
  • I know this is very old, but you can do `final INotificationManager iNotificationManager = INotificationManager.Stub.asInterface( ServiceManager.getService(Context.NOTIFICATION_SERVICE));` and get the actual running service instance and not a re-created per-package one. Will this allow you to check for other packages without ITE? – Alex Newman Aug 25 '17 at 19:43
2

See if you can use NotificationManagerCompat.areNotificationsEnabled() https://developer.android.com/reference/android/support/v4/app/NotificationManagerCompat.html#areNotificationsEnabled()

Android 4.1: How to check notifications are disabled for the application?

Community
  • 1
  • 1
jak10h
  • 519
  • 4
  • 11
  • NotificationManagerCompat.areNotificationsEnabled() gives whether notifications are enabled for the running application. What is needed is to check if a given application (with UID and package name) has notifications turned off (block all) or not – Vadiraj Purohit Oct 08 '16 at 09:57