Android 4.1:如何检查通知被禁用的应用程序?
Android 4.1为用户提供了一个checkbox来禁用特定应用程序的通知。
但作为开发者,我们无法知道通知的通知是否有效。
我真的需要检查当前应用程序的通知是否被禁用,但是在API中找不到任何设置。
有没有办法在代码中检查这个设置?
你不能100%不能。
在这个Google I / O 2012video中被问及新的通知的项目负责人声明你不能。
编辑
2016更新:现在你可以检查它,就像这个Google I / O 2016video中所说的那样。
使用支持库中的NotificationManagerCompat.areNotificationsEnabled()
来检查通知是否在API 19+上被阻止。 API 19下面的版本将返回true(启用通知)。
其实这很容易做到:
/** * Created by desgraci on 5/7/15. */ public class NotificationsUtils { private static final String CHECK_OP_NO_THROW = "checkOpNoThrow"; private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION"; public static boolean isNotificationEnabled(Context context) { AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); ApplicationInfo appInfo = context.getApplicationInfo(); String pkg = context.getApplicationContext().getPackageName(); int uid = appInfo.uid; Class appOpsClass = null; /* Context.APP_OPS_MANAGER */ try { 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, uid, pkg) == AppOpsManager.MODE_ALLOWED); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return false; } }
来自@blundell的回答是正确的,但在较新的版本中有一个小的变化。
NotificationManagerCompat.from(context).areNotificationsEnabled()
似乎没有办法查询通知状态。
我推荐这个:
- 用通知devise你的应用程序。
- 让用户禁用来自应用程序设置的通知。
- 检查通知是否被点击。 如果用户单击通知,请将其保存到首选项。
- 在您的应用程序中,如果通知设置处于打开状态,并且用户是Android 4.1+(API 16),但是如果用户在某些日/星期内未点击通知,则假定用户已禁用通知。
不是100%正确的。 但是这个意见。
例如,如果用户在10-15天内没有点击任何应用程序通知,他可能会禁用它
如果你正在使用Xamarin,你需要这个答案,你可以使用这个代码:
//return true if this option is not supported. public class NotificationsUtils { private const String CHECK_OP_NO_THROW = "checkOpNoThrow"; private const String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION"; public static bool IsNotificationEnabled(global::Android.Content.Context context) { AppOpsManager mAppOps = (AppOpsManager) context.GetSystemService(global::Android.Content.Context.AppOpsService); ApplicationInfo appInfo = context.ApplicationInfo; String pkg = context.ApplicationContext.PackageName; int uid = appInfo.Uid; try { var appOpsClass = Java.Lang.Class.ForName("android.app.AppOpsManager"); var checkOpNoThrowMethod = appOpsClass.GetMethod(CHECK_OP_NO_THROW,Java.Lang.Integer.Type,Java.Lang.Integer.Type,new Java.Lang.String().Class);//need to add String.Type var opPostNotificationValue = appOpsClass.GetDeclaredField (OP_POST_NOTIFICATION); var value = (int)opPostNotificationValue.GetInt(Java.Lang.Integer.Type); var mode = (int)checkOpNoThrowMethod.Invoke(mAppOps,value, uid, pkg); return (mode == (int)AppOpsManagerMode.Allowed); } catch (Exception) { System.Diagnostics.Debug.WriteLine ("Notification services is off or not supported"); } return true; } }