整理下安卓跳转通知设置页面的代码,如下:
常量补充:
private static final String CHECK_OP_NO_THROW = "checkOpNoThrow";private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";
1、android check通知是否开启代码
public static boolean isNotificationEnabled(Context context) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {return isEnableV26(context);} else {return isEnableV19(context);}}/*** Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT* 19及以上** @param context* @return*/public static boolean isEnableV19(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;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 = (Integer) opPostNotificationValue.get(Integer.class);return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) == AppOpsManager.MODE_ALLOWED);} catch (ClassNotFoundException e) {MyLog.e(sTAG, e);} catch (NoSuchMethodException e) {MyLog.e(sTAG, e);} catch (NoSuchFieldException e) {MyLog.e(sTAG, e);} catch (InvocationTargetException e) {MyLog.e(sTAG, e);} catch (IllegalAccessException e) {MyLog.e(sTAG, e);}return false;}/*** Build.VERSION.SDK_INT >= Build.VERSION_CODES.O* 针对8.0及以上设备** @param context* @return*/public static boolean isEnableV26(Context context) {try {NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);Method sServiceField = notificationManager.getClass().getDeclaredMethod("getService");sServiceField.setAccessible(true);Object sService = sServiceField.invoke(notificationManager);ApplicationInfo appInfo = context.getApplicationInfo();String pkg = context.getApplicationContext().getPackageName();int uid = appInfo.uid;Method method = sService.getClass().getDeclaredMethod("areNotificationsEnabledForPackage", String.class, Integer.TYPE);method.setAccessible(true);return (boolean) method.invoke(sService, pkg, uid);} catch (Exception e) {MyLog.e(sTAG, e);}return false;}
2、跳转到通知页面
public static void gotoNotificationSetting(Activity activity) {ApplicationInfo appInfo = activity.getApplicationInfo();String pkg = activity.getApplicationContext().getPackageName();int uid = appInfo.uid;try {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {Intent intent = new Intent();intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);//这种方案适用于 API 26, 即8.0(含8.0)以上可以用intent.putExtra(Settings.EXTRA_APP_PACKAGE, pkg);intent.putExtra(Settings.EXTRA_CHANNEL_ID, uid);//这种方案适用于 API21——25,即 5.0——7.1 之间的版本可以使用intent.putExtra("app_package", pkg);intent.putExtra("app_uid", uid);activity.startActivityForResult(intent, AppConst.REQUEST_SETTING_NOTIFICATION);} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {Intent intent = new Intent();intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);intent.addCategory(Intent.CATEGORY_DEFAULT);intent.setData(Uri.parse("package:" + GlobalData.app().getPackageName()));activity.startActivityForResult(intent, AppConst.REQUEST_SETTING_NOTIFICATION);} else {Intent intent = new Intent(Settings.ACTION_SETTINGS);activity.startActivityForResult(intent, AppConst.REQUEST_SETTING_NOTIFICATION);}} catch (Exception e) {Intent intent = new Intent(Settings.ACTION_SETTINGS);activity.startActivityForResult(intent, AppConst.REQUEST_SETTING_NOTIFICATION);MyLog.e(sTAG, e);}}
3、但是目前存在两个已知问题。
(1)优购手机(UOOGOU T10 Android 5.1.1) check通知权限,关闭的通知权限, 也会isNotificationEnabled函数也会返回true,check权限不准,目前在排查,有结论了再在博客添加。
(2)小米手机部分系统跳转到通知设置页了,但是却屏蔽了开启按钮的显示。 很诡异。
我测试的问题手机是 米五(MIUI 9 8.4.27 开发板 Android 8.0.0) 和 小米6x (MIUI 10.0 稳定版 Android 8.1.0)
截图如下:
如果大家说有更好地解决方案麻烦留言评论,谢谢。