Android detect app notification permission - adaptation 8.0

Keywords: SDK

In general, Api 19 has no notification management before. It is enabled by default, regardless.

Api 19-24 adds the notification management function, but does not open the interface to detect whether notifications are enabled. Developers can only use reflection to obtain permission values.

Api 24, notification manager provides areNotificationsEnabled() method to detect notification permission.

The above scenarios have been considered in the support package. areNotificationsEnabled() has been opened in 24.1.0. By default, it returns true below 19, and 19-24 returns the corresponding reflection value. Above 24, it is detected with the native NotificationManager.

The special case is that some domestic machines have been added with the notice related customization function, so the developers can't control or detect it, and they are totally blind. For example, whether the following notifications are displayed in the status bar management.

That is to say, in most cases, we use:

NotificationManagerCompat.from(context).areNotificationsEnabled() 

It can adapt to most models except some domestic ones. There is no way to deal with special models for the time being. Please let me know if you have any partners who know what to do.

The source code of areNotificationsEnabled is also very simple. Different methods are used according to the old tune of sdk version. areNotificationsEnabled is called for 24 and above. Reflection is used for 24 and below, and it doesn't matter for 19 and below.

/**
     * Returns whether notifications from the calling package are not blocked.
     */
    public boolean areNotificationsEnabled() {
        if (Build.VERSION.SDK_INT >= 24) {
            return mNotificationManager.areNotificationsEnabled();
        } else if (Build.VERSION.SDK_INT >= 19) {
            AppOpsManager appOps =
                    (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
            ApplicationInfo appInfo = mContext.getApplicationInfo();
            String pkg = mContext.getApplicationContext().getPackageName();
            int uid = appInfo.uid;
            try {
                Class<?> 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(appOps, value, uid, pkg)
                        == AppOpsManager.MODE_ALLOWED);
            } catch (ClassNotFoundException | NoSuchMethodException | NoSuchFieldException
                    | InvocationTargetException | IllegalAccessException | RuntimeException e) {
                return true;
            }
        } else {
            return true;
        }
    }

Posted by binarymonkey on Fri, 03 Jan 2020 17:45:33 -0800