如何知道是否为Android中的应用程序启用了通知? [英] How to know whether Notifications are enabled or not for an application in android?
问题描述
我有一个ListView,其中包含已安装的应用程序列表,对于每个应用程序,我需要知道是否启用了通知。
当前,我正在使用以下代码来了解是否已启用通知:
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);
我遇到以下异常:
原因: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:在com.android.internal.app.IAppOpsService $ Stub $ Proxy.checkOperation(IAppOpsService.java:343)
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)
我已包含
<uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS"/>
仍然出现相同的错误。
无论是否被阻止,我都可以使用什么api获取值
Still I'm getting the same error. Using what apis can I get the value whether it is blocked or not
推荐答案
恐怕这仅适用于当前应用程序。这就是为什么 NotificationManager
的公共API对当前软件包具有函数 areNotificationsEnabled()
的原因。
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.
当查看android源代码时,我发现 AppNotificationSettings
-应用通知设置。第一个开关指示通知是否被阻止。切换侦听器为此处,它指向 NotificationBackend
。在此类中,有方法:
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:
公共布尔型getNotificationsBanned(String pkg,int uid)
使用 INotificationManager
(由 .aidl
文件在编译过程中生成的类)及其方法:
which uses INotificationManager
( a class generated from .aidl
file during compilation) and it's method:
boolean areNotificationsEnabledForPackage(String pkg,int uid);
这是Android私有API,不能简单地调用。所以我尝试了反思:
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();
}
但是,如您所见,必须先创建 NotificationManager
。可悲的是,此类是为包创建的。因此,上面的代码仅适用于:
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());
但是这不起作用:
//InvocationTargetException will be thrown.
boolean blocked = (boolean) areNotificationsEnabledForPackage.invoke(obj, "com.android.camera", 10040);
结论:
无法完成。
这篇关于如何知道是否为Android中的应用程序启用了通知?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!