如何知道android中的应用程序是不是启用了通知?
Posted
技术标签:
【中文标题】如何知道android中的应用程序是不是启用了通知?【英文标题】:How to know whether Notifications are enabled or not for an application in android?如何知道android中的应用程序是否启用了通知? 【发布时间】:2017-02-11 11:07:29 【问题描述】:我有一个 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:在 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)
我已经加入了
<uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS"/>
我仍然遇到同样的错误。 使用什么api可以获取是否被阻止的值
【问题讨论】:
您使用哪个 API 版本来构建应用程序以及您在哪个 android 版本上测试您的应用程序?我问这个是因为对于 Android 6 及更高版本中的某些敏感权限,您需要在运行时获得用户的权限。 developer.android.com/training/permissions/requesting.html 看看NotificationManager.getNotificationPolicy()
是否为您服务。 Link
【参考方案1】:
恐怕这仅适用于当前应用程序。这就是为什么 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);
结论:
做不到。
【讨论】:
我知道这已经很老了,但是您可以通过final INotificationManager iNotificationManager = INotificationManager.Stub.asInterface( ServiceManager.getService(Context.NOTIFICATION_SERVICE));
获取实际运行的服务实例,而不是重新创建的每个包的实例。这是否允许您在没有 ITE 的情况下检查其他包?【参考方案2】:
看看能不能用 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?
【讨论】:
NotificationManagerCompat.areNotificationsEnabled() 给出是否为正在运行的应用程序启用通知。需要检查给定应用程序(带有 UID 和包名称)是否关闭了通知(全部阻止)以上是关于如何知道android中的应用程序是不是启用了通知?的主要内容,如果未能解决你的问题,请参考以下文章
如何在xamarin android中启用浮动通知和锁屏通知(Java或Kotlin都可以)