如何知道Android中的应用程序是否启用了通知?

时间:2016-10-03 13:22:12

标签: android android-notifications android-settings

我有一个ListView,其中包含已安装的应用程序列表,对于每个应用程序,我需要知道是否启用了通知。 目前,我使用以下代码了解是否已启用通知:

jqXHR

我遇到以下异常:

  

引起:java.lang.SecurityException:uid 10062没有    android.permission.UPDATE_APP_OPS_STATS。   W / System.err:在android.os.Parcel.readException(Parcel.java:1683)   W / System.err:在android.os.Parcel.readException(Parcel.java:1636)   W / System.err:at com.android.internal.app.IAppOpsService $ Stub $ Proxy.checkOperation(IAppOpsService.java:343)

我已经

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

我仍然遇到同样的错误。 使用什么api我可以得到它是否被阻止的值

Using what apis can I get these values?

2 个答案:

答案 0 :(得分:7)

我担心这只适用于当前的应用程序。这就是为什么NotificationManager的公共API具有当前包的函数areNotificationsEnabled()

在查看android源代码时,我找到了AppNotificationSettings - 应用程序通知设置。第一个开关指示通知是否被阻止。切换监听器为here,指向NotificationBackend。在这个课程中,有方法:

public boolean getNotificationsBanned(String pkg, int uid)

使用INotificationManager(在编译期间从.aidl文件生成的类)及其方法:

boolean areNotificationsEnabledForPackage(String pkg, int uid);

这是Android私有API,不能简单地调用。所以我尝试了反思:

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

<强>结论:

无法完成。

答案 1 :(得分:2)