Android 8.0+通知栏(Notification)适配详解,判断通知权限是否打开,并跳转至通知管理页面
前不久因为API26(Android 8.0)以上的设备无法显示通知栏,所以网上查阅了比较多了资料,得出结论,API26以后引入了通知渠道这么个东西,然后就写了一篇问题对应的博文:Android 8.0通知栏(Notification)适配,在模拟上是完美运行,可是当我前两天安装到真机上测试时,咦?怎么又无效了?然后我就想着,是不是通知权限没打开?因为模拟器上很多权限的控制和真机上差别很大,我打开设置一看,还真是!那么本文就接着Android 8.0通知栏(Notification)适配作一个补充。
文章目录
- Android 10 真机测试效果:
- 判断通知权限是否打开
- 一行代码判断
- areNotificationsEnabled() 的源码(可忽略)
- 跳转到通知管理页面
- 方法逻辑:
- 补充
- 方法逻辑
Android 10 真机测试效果:
判断通知权限是否打开
一行代码判断
我们要打开通知 管理页面 第一步当然是判断 通知权限是否打开了? ,打开了我们就不需要跳转到通知管理页面了,没打开我们才进行跳转。
这里我们用NotificationManagerCompat提供的 .areNotificationsEnabled() 方法来判断通知权限是否打开,返回的是boolean值
NotificationManagerCompat.from(this).areNotificationsEnabled()
注意:这个方法只适用于API19(Android 4.4)以上,API19以下会直接返回true,当然我们不是特殊开发也可以忽略了,毕竟现在市场上低于 Android4.4 的手机恐怕不好找,而且貌似Android4.4以下的对权限这块也没有太严格~
areNotificationsEnabled() 的源码(可忽略)
我们来看看 areNotificationsEnabled() 的源码,源码可以很清晰明朗地看到,API24以上直接调用 mNotificationManager.areNotificationsEnabled();
方法,而 API19 -API 23 则是通过反射的方式来获取,API 19 以下就直接返回 true 了
/*** 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;}}
跳转到通知管理页面
通知权限判断完了当然是要根据判断结果来进行跳转了,上面我们可以知道 NotificationManagerCompat.from(this).areNotificationsEnabled()
是会返回 boolean 值的,true 代表权限已经打开,反之则没有打开,这里我们可以写一个 if 语句根据返回结果来进行判断,这里直接给一个现成的方法吧
方法逻辑:
- 首先判断 通知权限是否打开
- 如果判断结果是:false(权限没打开),再进行当前手机的 API 判断
- 通过判断API,来调用不同的方法,实现跳转到应用通知设置的页面
private boolean intent(Context context) {//判断应用的通知权限是否打开,返回Boolean值if (!NotificationManagerCompat.from(context).areNotificationsEnabled()) {Intent localIntent = new Intent();//判断API,跳转到应用通知管理页面if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//8.0及以上localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));} else (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//8.0以下localIntent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");localIntent.putExtra("app_package", context.getPackageName());localIntent.putExtra("app_uid", context.getApplicationInfo().uid);}context.startActivity(localIntent);return false;} return true;}
补充
这里补充一下 Android 8.0 +的 Notification通知栏消息 的使用,相对于以前也只是加了一个NotificationChannel通知渠道,想要详细看的可以去我前一篇关于通知栏的博客:Android 8.0通知栏(Notification)适配
方法逻辑
- 首先通过上面的 通知权限判断 方法判断通知权限是否打开
- 打开了的话判断当前手机的API,如果是在 26 (Android 8.0)以上则多实例化一个NotificationChannel对象,并传入一个 ID(用户不可见,要保证id的唯一性) 和一个 Name(用户能看到) ,最后是一个通知的优先级,这里我设置的 高(IMPORTANCE_HIGH)
- 如果API 在 26 以下,我们则直接调用以前使用的方法即可,这样就可以兼容上下API了
public void show(Context context, String title, String msg) {if (intent(context)) {NotificationManager manager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);Notification notification = null;if (Build.VERSION.SDK_INT >= 26) {//API26以上的方法NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_HIGH);manager.createNotificationChannel(channel);notification = new Notification.Builder(context, "id").setContentTitle(title).setContentText(msg).setSmallIcon(R.mipmap.img_icon).build();} else {//API26以下notification = new Notification.Builder(context).setContentTitle(title).setContentText(msg).setSmallIcon(R.mipmap.img_icon).build();}manager.notify(1, notification);}}
如果文章对你还算有点帮助,点个赞吧!
Android 8.0+通知栏(Notification)适配详解,判断通知权限是否打开,并跳转至通知管理页面相关推荐
- 【Android-】android 8.0 通知栏Notification适配、自定义铃声及其channel介绍
android 8.0 通知栏Notification适配以及自定义铃声 一.8.0手机 通知栏适配 二.自定义铃声所遇到的坑 三.Android O Preview 之 通知渠道(Notificat ...
- android 7.0 按钮崩溃,Android 7.0调用相机崩溃详解及解决办法
Android 7.0调用相机崩溃解决办法 错误提示: android.os.FileUriExposedException: file:///storage/emulated/0/DCIM/IMG_ ...
- android最新相机打不开,Android 7.0调用相机崩溃详解及解决办法
Android 7.0调用相机崩溃解决办法 错误提示: android.os.FileUriExposedException: file:///storage/emulated/0/DCIM/IMG_ ...
- android 8.0的imei简书,Android 8.0通知栏渠道,渠道组的适配和使用
Android 8.0通知栏渠道,渠道组的适配和使用 推广一下 博客 android 8.0开始引入了渠道组的概念,app可以对通知类型进行细分,比如划分为:广告消息,私聊消息,群聊消息等. 但其实到 ...
- android屏幕适配详解
android屏幕适配详解 官方地址:http://developer.android.com/guide/practices/screens_support.html 一.关于布局适配建议 1.不要 ...
- 关于android的4.2的0文件夹的详解
关于android的4.2的0文件夹的详解 ---- android 4.0 ---- 在galaxy nexus(GN)手机上userdata分区很大,被挂在/data目录,用户的数据通常是放在sd ...
- android ble蓝牙接收不到数据_Android蓝牙4.0 Ble读写数据详解 -2
Android蓝牙4.0 Ble读写数据详解 -2 上一篇说了如何扫描与链接蓝牙 这篇文章讲讲与蓝牙的数据传输,与一些踩到的坑. 先介绍一款调试工具,专门调试Ble蓝牙的app.名字叫:nRF-Con ...
- android 4.2目录结构,关于android的4.2的0文件夹的详解(目录结构挂载分析)
关于android的4.2的0文件夹的详解 ---- android 4.0 ---- 在galaxy nexus(GN)手机上userdata分区很大,被挂在/data目录,用户的数据通常是放在sd ...
- Android Doze and App Standby模式详解
Android Doze and App Standby模式详解 来源:腾云阁 https://www.qcloud.com/community Optimizing for Doze and Ap ...
最新文章
- 技术人员必须了解的产品设计基本概念
- win10 uwp 按下等待按钮
- java 图形 登录_Java图形界面——登录框
- PHP 中 new static 和 new self 的区别
- Cmake之基本语法
- 不懂开发的运维,未来该如何发展?
- python 爬虫保存为word_微信公众号文章爬虫,本地word文档保存
- CPA、CPS、CPC、CPM推广是什么意思?
- 一步一步搭建自己的web系统(一):搭建后端服务
- R5 4650G和R5 5600G差距
- 基于Matlab的三角函数方程组解算方法
- 网络原理TCP IP
- LR---Loadrunner11破解方法
- cdn服务器pnk_cdn服务器是什么
- GitHub 标星 1000+ 的开源电子书
- 第九篇论文读后总结-相似森林
- 安卓sdk过高,没法打开摄像头权限
- worksheets 和 sheets 的不同
- 南邮 | Linux实验一:Linux 基本命令 权限管理
- Nodejs-Express框架