关于安卓判断通知权限

简介: 与相机等权限大体一致,通知权限也是系统权限之一,开启该权限的方法有两种。一种是直接打开app的系统设置页面,找到通知管理,开启通知即可。但是大部分app是会有提醒功能,如果app没有开启通知权限,会弹出一个弹框,引导用户跳转到设置页面去手动开启。

作为Android开发,通知功能现在基本上是每一个app必要的需求,无论是集成第三方通知SDK,还是自己实现,开启通知权限是必要的条件。

本人集成过腾讯推送、firebase推送,国内app使用腾讯推送居多,而上架Google 商场的app,基本首选是firebase ,因为是第三方平台,一般都配有开发文档,按照步骤操作即可,但是呢?很多文档里面是没有涉及到判断是否app开启通知权限的内容,毕竟这部分属于app原则上说,不是第三方该考虑的问题,只会提醒要开启权限,今天这篇文章就来讲讲开启通知权限。

与相机等权限大体一致,通知权限也是系统权限之一,开启该权限的方法有两种。一种是直接打开app的系统设置页面,找到通知管理,开启通知即可。但是大部分app是会有提醒功能,如果app没有开启通知权限,会弹出一个弹框,引导用户跳转到设置页面去手动开启。

跳转系统设置页面去开启不难,难点是在判断是否开启权限,在NotificationManagerCompat还没出现之前(具体哪个API版本推出这个类不清楚),需要分API来判断,有两个阶段,分别是Android系统版本4.4以上到8.0以下,另外一个是8.0以上。

我们判断通知权限一般是用NotificationManager,但是在4.4以上到8.0以下是无法使用NotificationManager的。

也就是说在这系统版本阶段,要判断是否开启通知权限,方法不一样,这种情况很正常,说明Android 版本更新的时候,没有做向下做兼容旧版本这件事,所以要使用不同的方法来实现,用同一套方法做不到兼容性。

具体代码如下:

public class NoticePermissionUtil {
 
    private static final String CHECK_OP_NO_THROW = "checkOpNoThrow";
    private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";
 
    //调用该方法获取是否开启通知栏权限
    public static boolean isNotifyEnabled(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            return isEnableV26(context);
        } else {
            return isEnabledV19(context);
        }
    }
 
    /**
     * 8.0以下判断
     *
     * @param context api19  4.4及以上判断
     * @return
     */
    private static boolean isEnabledV19(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 (Exception e) {
            e.printStackTrace();
            return true;
        }
    }
 
 
    /**
     * 8.0及以上通知权限判断
     *
     * @param context
     * @return
     */
    private static boolean isEnableV26(Context context) {
        ApplicationInfo appInfo = context.getApplicationInfo();
        String pkg = context.getApplicationContext().getPackageName();
        int uid = appInfo.uid;
        try {
            NotificationManager notificationManager = (NotificationManager)
                    context.getSystemService(Context.NOTIFICATION_SERVICE);
            @SuppressLint("DiscouragedPrivateApi")
            Method sServiceField = notificationManager.getClass().getDeclaredMethod("getService");
            sServiceField.setAccessible(true);
            Object sService = sServiceField.invoke(notificationManager);
 
            Method method = null;
            if (sService != null) {
                method = sService.getClass().getDeclaredMethod("areNotificationsEnabledForPackage"
                        , String.class, Integer.TYPE);
                method.setAccessible(true);
            }
            return (boolean) method.invoke(sService, pkg, uid);
        } catch (Exception e) {
            return true;
        }
    }
}

我们直接调用isNotifyEnabled()即可,返回true则说明已经开启通知权限,false则没有,当false的时候跳转到设置页面去开启就行,这部分代码这里就不写了。下面讲NotificationManagerCompat会有。

那么NotificationManagerCompat就是NotificationManager兼容性库,适用于旧版平台,也就是说使用NotificationManagerCompat来判断是否开启通知权限就行,兼容旧版本。那么代码上就简单了。

public class CheckNotifyPermissionUtils {
 
 
    /**
     * 系统层面通知开关有没有开启
     * Build.VERSION.SDK_INT >= 24
     * Build.VERSION.SDK_INT >= 19
     *
     * @param mContext
     * @return
     */
    public static boolean checkNotifyPermission(Context mContext) {
        NotificationManagerCompat manager = NotificationManagerCompat.from(mContext);
        boolean isOpened = manager.areNotificationsEnabled();
        return isOpened;
    }
 
 
    /**
     * 如果通知未打开 跳转到通知设定界面
     * @param mContext
     */
    public static void tryJumpNotifyPage(Context mContext) {
        Intent intent = new Intent();
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, mContext.getPackageName());
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
                intent.putExtra("app_package", mContext.getPackageName());
                intent.putExtra("app_uid", mContext.getApplicationInfo().uid);
            } else {
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                intent.setData(Uri.parse("package:" + mContext.getPackageName()));
            }
            mContext.startActivity(intent);
        } catch (Exception e) {
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            Uri uri = Uri.fromParts("package", mContext.getPackageName(), null);
            intent.setData(uri);
            mContext.startActivity(intent);
        }
    }
}

直接调用checkNotifyPermission()方法即可判断是否开启通知权限,另外tryJumpNotifyPage()提供对各版本系统跳转到设置页面的方法,调用即可。

that's all.

相关文章
|
19天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
20 0
|
19天前
|
Java Shell Android开发
android 权限申请
android 权限申请
21 5
|
19天前
|
XML API 数据库
Android权限
Android权限 【5月更文挑战第3天】
19 0
|
19天前
|
Android开发 开发者
Android打开开发者权限
Android打开开发者权限
19 0
|
19天前
|
Android开发
Android 9.0中sdcard 的权限和挂载问题
Android 9.0中sdcard 的权限和挂载问题
14 0
|
19天前
|
Android开发
Android修改默认system/bin/下可执行程序拥有者和权限,使用实例,只有root和系统app权限才能执行某个命令。
Android修改默认system/bin/下可执行程序拥有者和权限,使用实例,只有root和系统app权限才能执行某个命令。 【5月更文挑战第2天】
23 0
|
19天前
|
Android开发
android 12 U盘 /mnt/media_rw 下读取文件异常 没有权限
android 12 U盘 /mnt/media_rw 下读取文件异常 没有权限
68 0
|
19天前
|
XML Android开发 数据安全/隐私保护
android 11后文件读写访问权限申请
android 11后文件读写访问权限申请
19 0
|
19天前
|
Android开发
安卓动态申请权限
安卓动态申请权限
22 0
|
19天前
|
存储 Java API
Android系统 文件访问权限笔记
Android系统 文件访问权限笔记
114 1