Android:检查通知权限并跳转到通知设置界面

原文地址:https://www.jianshu.com/p/1e27efb1dcac

声明:该方案只对API19及以上版本有效

一、目标需求

最近项目中在完善推送功能,需要进入APP时检测一下是否开启了推送权限,如果没有开启弹窗提醒,当用户点击弹窗时直接跳转到APP的通知设置界面,就像下面这种:
效果

二、需求实现

1、检测是否开启通知权限

接到需求时一脸懵,不知道咋实现,先是一番搜索,搜索后得知可以通过NotificationManagerCompat 中的 areNotificationsEnabled()来判断是否开启通知权限。
查阅官方文档可知 NotificationManagerCompat 在 android.support.v4.app包中,是API 22.1.0 中加入的。而 areNotificationsEnabled()则是在 API 24.1.0之后加入的。

areNotificationsEnabled 只对 API 19 及以上版本有效,低于API 19 会一直返回true

2、跳转到通知设置界面

假设没有开启通知权限,点击之后就需要跳转到 APP的通知设置界面,对应的Action是:Settings.ACTION_APP_NOTIFICATION_SETTINGS, 这个Action是 API 26 后增加的。APP的通知设置界面如下图:

App的通知设置界面
如果在部分手机中无法精确的跳转到 APP对应的通知设置界面,那么我们就考虑直接跳转到 APP信息界面,对应的Action是:Settings.ACTION_APPLICATION_DETAILS_SETTINGS。APP信息界面如下图:
App的信息界面

3、代码实现:

/**
 * 检测是否有通知栏权限
 *
 * @author syl
 * @time 2019/5/15 10:35 AM
 */
public class NotificationsUtils {


    public static boolean isNotificationEnabled(Context context) {
        return NotificationManagerCompat.from(context.getApplicationContext()).areNotificationsEnabled();
    }

    public static void openPush(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //这种方案适用于 API 26, 即8.0(含8.0)以上可以用
            Intent intent = new Intent();
            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra(Settings.EXTRA_APP_PACKAGE, activity.getPackageName());
            intent.putExtra(Settings.EXTRA_CHANNEL_ID, activity.getApplicationInfo().uid);
            activity.startActivity(intent);
        } else {
            PermissionUtil.toPermissionSetting(activity);
        }
    }
}

PermissionUtil的部分代码

    /**
     * 跳转到权限设置
     *
     * @param activity
     */
    public static void toPermissionSetting(Activity activity) {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
            toSystemConfig(activity);
        } else {
            try {
                toApplicationInfo(activity);
            } catch (Exception e) {
                e.printStackTrace();
                toSystemConfig(activity);
            }
        }
    }

    /**
     * 应用信息界面
     *
     * @param activity
     */
    public static void toApplicationInfo(Activity activity) {
        Intent localIntent = new Intent();
        localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        localIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        localIntent.setData(Uri.fromParts("package", activity.getPackageName(), null));
        activity.startActivity(localIntent);
    }

    /**
     * 系统设置界面
     *
     * @param activity
     */
    public static void toSystemConfig(Activity activity) {
        try {
            Intent intent = new Intent(Settings.ACTION_SETTINGS);
            activity.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

4、踩坑记录

A: com.android.support包的版本

因为 NotificationManagerCompat 是 22.1.0才有的,其中的 areNotificaitonEnabled() 是 24.1.0 才有的,Settings.ACTION_APP_NOTIFICATION_SETTINGS 是 26 才有的,所以,为了保证这些内容在不同版本中生效,最好在 gradle文件中 support 的版本升级到最新。如:

implementation ‘com.android.support:appcompat-v7:27.1.1’

B: 部分国产手机中没有APP通知设置页面

在部分国产手机系统中,Settings.ACTION_APPLICATION_DETAILS_SETTINGS对应的Activity是不存在的,比如:锤子坚果3——OC105 API25。
所以,在坚果3手机上,最终会走我们代码中的 catch 节点,然后进入到 应用信息界面。
下面两张图分别是 锤子坚果3 手机的截图。第一张是 设置–通知中心的界面,点击之后只是一个开关的开启和关闭,并没有再进入详细的通知设置界面。第二张是 应用管理–应用程序管理–应用信息界面, 点击其中的 允许推送通知时也只是开关的开启和关闭。

设置--通知中心
应用信息

C: 部分国产手机 APP通知设置界面中没有开启和关闭的操作

部分国产手机中Settings.ACTION_APPLICATION_DETAILS_SETTINGS对应的Activity并不是我们期望的通知设置界面。比如,小米6。小米6中 Settings.ACTION_APPLICATION_DETAILS_SETTINGS对应的通知设置界面如下:
小米6
这完全不是我们需要的界面啊。。。里面并没有我们想要的开关啊。而且,在小米6中 Settings.ACTION_APPLICATION_DETAILS_SETTINGS 对应的应用信息界面中,点击其中的 通知管理 之后跳转的也是上面图中的样子。
但是,如果我们手动的从 设置–通知和状态栏–通知管理 进入我们应用的通知设置界面时,就可以正常的看到 允许通知的开关,如下图:

小米6

对于小米6手机的这个情况,分析了一阵子之后还是没找到解决办法。本来想着通过log确认一下上图中的界面到底是哪个Activity,但非常郁闷的是Log中只得到了com.android.settings/.SubSettings 这么一个地址,之前没见过这个地址,然后继续搜索。
在看完 https://www.cnblogs.com/Lefter/archive/2013/04/27/3048010.htmlhttps://blog.csdn.net/hfreeman2008/article/details/52778992 之后,明白了 .SubSettings 是干啥的了。也大致推断出为啥在小米6上得不到我们想要的界面了——他们在定制系统时更改了通知设置界面对应的Fragment!!!!
此时,真想对雷布斯说一句:I’m not ok!!!

三、附录

1、测试结果说明

手机型号 系统版本 测试结果
Vivo X9s 7.1.2 正常跳转到通知设置界面
荣耀10 8.1.0 正常跳转到通知设置界面
红米note4x 7.0 正常跳转到通知设置界面
Oppo R7 plus 5.0 正常跳转到通知设置界面
ZTE BA910 5.1 正常跳转到通知设置界面
Oppo R15 8.1.0 正常跳转到通知设置界面
三星盖乐世On5 7.1.1 正常跳转到通知设置界面
360Vizza 7.1.1 正常跳转到通知设置界面
魅族Mx3 4.4 进入APP设置界面
华为荣耀4X 4.4 进入APP设置界面
锤子坚果3 7.1.2 进入APP设置界面
小米6 8.0.0 进入的页面中没有通知开关!!!!

2、参考链接

(1)通知设置的参考链接
(2)SubSettings 和 Settings 的参考链接

猜你喜欢

转载自blog.csdn.net/abc6368765/article/details/90270064