NotificationListenerService不能监听到通知
链接:https://www.zhihu.com/question/33540416/answer/113706620
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
所属:android.service.notification.NotificationListenerService
作用:监听通知栏内容变化的服务
- extends Service,abstract class(意味着第三方可以实现去接收通知栏的通知数据)。
- Added in API level 18(Android 4.3)。
- 应用场景:智能手表(Google官方的Android Wear手机端App,通知消息同步到手表。如下图)、红包助手(监听通知栏的微信红包消息)等。
- Service bind时机:在系统的设置通知授权中勾选并授权时。
- 回调时机:有新通知或通知被移除或通知排序变化时系统回调。
----坑------
应用进程被杀后再次启动时,服务不生效(没有bindService)(在下图所示的蓝色列表名单中,不在红色的存活名单中)。
影响:通知栏有内容变更,服务无法感知。
还原方法:重启手机
必现手机(方便调试):小米Note Pro,清除后台应用后。
我们要做的:让服务重生。
调试手段:查看存活的通知监听服务。
方法:adb shell dumpsys notification
<img src="https://pic4.zhimg.com/fad5065af404878506a7ed548f5854d7_b.jpg" data-rawwidth="964" data-rawheight="278" class="origin_image zh-lightbox-thumb" width="964" data-original="https://pic4.zhimg.com/fad5065af404878506a7ed548f5854d7_r.jpg">
蓝色:已授权的通知监听Service列表。
红色:当前存活的的通知监听Service列表。
调查思路:
一、第三方应用主动注册
二、触发系统重新bind
思路一:第三方应用主动注册
关键代码路径:
- android.service.notification.NotificationListenerService#registerAsSystemService
- android.app.INotificationManager.Stub#enforceSystemOrSystemUI
条件:
- 系统的uid或有android.permission.STATUS_BAR_SERVICE权限。
∴ 路不通。
思路二:触发系统重新bind
关键代码路径:
- com.android.server.notification.ManagedServices#rebindServices
三种方式触发:
- A && B(A:应用安装卸载或更新等的广播;B:上图蓝色列表中的服务有变化)。
- 系统的登录用户切换 。[pass]
- Settings.Secure.ENABLED_NOTIFICATION_LISTENERS的Settings值有变更。
第三方有权利触发的方式(源码分析得知 1B= 3):
- Service的disable,会有Intent.ACTION_PACKAGE_CHANGED广播,并且从上图蓝色列表中移除。
利用这一特性,把应用的NotificationListenerService实现类disable再enable,即可触发系统rebind操作。
private void toggleNotificationListenerService() {
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(new ComponentName(this, com.xinghui.notificationlistenerservicedemo.NotificationListenerServiceImpl.class),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(new ComponentName(this, com.xinghui.notificationlistenerservicedemo.NotificationListenerServiceImpl.class),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}
问题解决。
补充:
1、怎样在代码中判断自己的服务是否在上图蓝色列表(通知已授权)中?
private static boolean isNotificationListenerServiceEnabled(Context context) {
Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(context);
if (packageNames.contains(context.getPackageName())) {
return true;
}
return false;
}
2、怎样发起通知授权流程。
startActivity(new Intent(NotificationConstants.ACTION_NOTIFICATION_LISTENER_SETTINGS));
NotificationListenerService不能监听到通知的更多相关文章
- oninput事件(解决onkeyup无法监听到复制黏贴)
change事件需要两个条件触发: a)当前对象属性改变,并且是由键盘或鼠标事件激发的(脚本触发无效) b)当前对象失去焦点(onblur) keypress 能监听键盘事件,但鼠标复制黏贴操作就 ...
- vue计算属性无法监听到数组内部变化
计算属性可以帮助我们简化代码,做到实时更新,不用再自己添加function去修改data. 首先看一下计算属性的基本写法(摘自官网) var vm = new Vue({ el: '#demo', d ...
- cordova-plugin-file-transfer 监听到下载成功,找不到文件 - 简书
原文:cordova-plugin-file-transfer 监听到下载成功,找不到文件 - 简书 下载成功后找不到下载文件 function download(fileEntry, uri) { ...
- laravel中observe不能监听到updated事件原因
//这种方式不行Student::where('id', $request->student_id)->update($student); $findStudent = Student:: ...
- UNLISTEN - 停止监听通知信息
SYNOPSIS UNLISTEN { name | * } DESCRIPTION 描述 UNLISTEN 用于删除一个现有的已注册的 NOTIFY 事件. UNLISTEN 取消当前 Postgr ...
- vue中watch和computed为什么能监听到数据的改变以及不同之处
先来个流程图,水平有限,凑活看吧-_-|| 首先在创建一个Vue应用时: var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } ...
- Zookeeper 对节点的 watch监听通知是永久的吗?为什么 不是永久的?
不是.官方声明:一个 Watch 事件是一个一次性的触发器,当被设置了 Watch 的数据发生了改变的时候,则服务器将这个改变发送给设置了 Watch 的客户端, 以便通知它们. 为什么不是永久的,举 ...
- Oracle LISTENER 主机名修改为IP地址后LISTENER无法监听到实例 oracle监听错误与hosts文件配置
为什么listener.ora文件里面HOST后面到底应该输入IP地址还是主机名.我的经验告诉我,这边最好使用主机名.很多的时候,一个机器绑定的不只一个IP地址,如HOST后面是IP地址,那么ORAC ...
- mui.fire 目标页无法监听到 触发事件
//获得详情页面 if(!detailPage){ detailPage = plus.webview.getWebviewById('detail.html'); } //触发详情页面的newsId ...
随机推荐
- S5PV210的IRAM应用
准备分析 IRAM的大小96k,其实前两个程序都在这里运行的,程序都小于16K.要实现的是从把IRAM从的前16k从IRAM的起始地址0xD0020000拷贝到0xD0024000 处,调用mai ...
- Awesomplete 屌爆了
自动完成,功能强大! 具体请参考 http://leaverou.github.io/awesomplete
- cat ,more, Less区别
使用cat more less都可以查看文本内容,但是它们三者有什么区别呢?more和less的功能完全重复吗?以下是我个人的总结,欢迎大家一起来分享 cat 连续显示.查看文件内容mo ...
- BZOJ_4326_[NOIP2015]_运输计划_(二分+LCA_树链剖分/Tarjan+差分)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=4326 给出一棵带有边权的树,以及一系列任务,任务是从树上的u点走到v点,代价为u到v路径上的权 ...
- epub3 in action: epub3文件格式简介
epub3文件就是一个符合epub3标准,以epub为扩展名的zip压缩文件.epub3标准则是基于html5.css3.svg等web标准以及mathML等来展示内容.下图就是一个简单epub3文件 ...
- MsoShapeType /InlineShape枚举
指定形状的类型或形状范围. 名称 值 说明 msoAutoShape 1 自选图形. msoCallout 2 标注. msoCanvas 20 画布. msoChart 3 图. msoCommen ...
- MongoDB 权限 验证
在MongoDB中,服务启动默认是没有权限验证的,就安全性方面来说,这肯定是不行的,所以需要加上权限验证. 既然是要进行权限验证,那肯定是得有用户的吧,所以权限验证的第一步就是给MongoDB库添加用 ...
- 使用IIS配合VS调试
当我们使用Visual Studio调试(Debug)的时候,通常我们会选择VS自带的ASP.NET Developerment Server(也是默认选项),当第一次调试的时候(按F5或Ctrl+F ...
- 【原】Windows中使用Redis基本入门教程
Redis是c编写基于Unix平台开发的一种内存KV数据库,官网上并没有给出Window的安装包,但MS基于redis发布了Windows版本. 下载链接: https://github.com/MS ...
- public staic void main 总结
jvm 就是java的操作系统.深入了解jvm很必要. public:该函数的修饰符,表示该函数是公有的,无需多言. static 对于函数的修饰,表明该方法为静态方法,可以通过类名直接调用,事项对于 ...