Android查看当前应用通知开启状态
来源:互联网 发布:淘宝上日本直邮几天 编辑:程序博客网 时间:2024/05/17 23:12
需求背景: 在我的项目里需要显示应用的通知状态,比如开启、关闭,看似一个小小的需求,发现调用常见的AppOpsManager在4.4以下手机因为没有这个api而闪退,为解决4.4以下手机的状态做了一些探索,下面是一个博主写得很好的例子拿来学习,另外在api 22版本里面可直接使用NotificationManagerCompat.areNotificationEnable()来获取开启状态值。最后遗憾地总结,在4.4以下版本及时用反射来调用状态实际也是不可行的,因为api源码的这句话,因此中断了我们的读取值,so,在4.4以下版本我写的状态值是"未知"
throw new SecurityException("Disallowed call for uid " + Binder.getCallingUid());
1、查阅资料
有问题找度娘,找到了这个帖子
https://segmentfault.com/q/1010000002508523
然后顺藤摸瓜找到了这个帖子
http://stackoverflow.com/questions/11649151/android-4-1-how-to-check-notifications-are-disabled-for-the-application
大致意思就是系统不想让你获取这个开关的状态,但是我们可以使用发射来获取这个值。
2、编码测试
直接使用大神代码片段,发现是反射了AppOpsManager这个类里面的checkOpNoThrow方法,
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
尝试运行是可以获取到的。
但是我们查阅官方文档可以发现,AppOpsManager这个类是api19以上才添加的,也就是说android4.3以下这个方法就失效了,代码测试下
果然…..是获取不到的
那么4.3以下怎么办呢,这边先说下结果吧,4.3以下是获取不到。尝试过程如下:
首先我们下下来setting源码,打开到手机到app的应用详情页,然后adb一把
- 1
- 1
会发现栈顶是om.Android.settings/.applications.InstalledAppDetails
好,那我们到setting里面找到InstalledAppDetails这个类,看代码会发现还是挺好理解的,看到这方法:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
应用详情里面的 ‘显示通知’ 按钮是由initNotificationButton这个方法来处理的,在这里我们可以看到,最终代码是nm.areNotificationsEnabledForPackage(mAppEntry.info.packageName) 这句话,那么重点来了,着重的看下INotificationManager这个类里面的areNotificationsEnabledForPackage这个方法,下面以这个nm为突破口,看到了INotificationManager,
既然这些是Notification的开关,那么NotificationManger肯定就会有应用,那我们就去看看NotificationManager:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
果然NotificationManager里面有这么个方法,看下这个IBinder的b对象,是获取的系统的notification的service,对比setting源码看下
Context源码如下
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
InstalledAppDetails.Java源码如下
- 1
- 2
- 1
- 2
好了,代码看到这里就发现 NotificationManager里面getService获取的nm对象跟InstalledAppDetails里的nm是获取的同一个实例,那么方法就来了。
思考一下,这边分两个步骤来得到我们想到的值
- 1、反射NotificationManager的getService()方法得到INotificationManager对象
- 2、反射INotificationManager的areNotificationsEnabledForPackage()方法得到状态值
通过上面的两步我们就能获取到最终的状态值了。
废话不多说,上代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
(方法命名欠妥当)迫不及待的跑一把看看,最终会发现:
为什么会这样呢?
INotificaitonManager源码是没有看到了,不过从NotificationManagerService入手可以发现 INotificationManager.Stub第一个binder实例,查看代码发现
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
重点在这个方法 checkCallerIsSystem():
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
看到这里相信大家都能看明白了,人家就是不想让非系统级的app用,就是这么任性。
备注: 参考博客地址 http://blog.csdn.net/zcllige/article/details/52444258
- Android查看当前应用通知开启状态
- Android查看当前应用通知开启状态
- 获取当前应用通知状态
- android 查看当前网络状态
- 通知开启状态判断
- android 获取应用通知是否开启
- android查看当前应用占用的内存空间
- Android获取应用详情页系统通知状态
- android M 如何获取设置应用通知开关状态
- android 发送状态通知
- Android判断当前应用通知是否打开,跳转到打开通知界面
- 查看MYSQL当前编码状态
- 7. 查看当前库状态
- Android 多媒体应用:开启摄像头、查看相册中的照片
- android:检查系统是否开启消息通知权限,app应用点击开启通知时跳转到app详情页面开启权限
- android 判断当前应用是否处于活动状态
- android 判断当前应用是否处于活动状态
- Android系统中查看某个应用当前流量的方法
- windows下的线程同步的方式
- ES6 let var 暂时性死区
- Spring Cloud微服架构之分布式配置中心(续)
- 关于web.xml中<web-app>报错解决方案
- 移动端将base64传给后台,后台解析出的图片一部分是白色的
- Android查看当前应用通知开启状态
- 内网穿透
- Totemsoft.SDK.Framework4.Graphics.Image.Serialized 命名空间
- ios开发之NSCharacterSet
- 全面理解虚拟DOM,实现虚拟DOM
- JS的内存问题
- iOS仿酒店入住离店日历(Calendar)选择
- 使用Maven搭建SSM框架教程
- 20170512