NotificationListenerService 安卓通知栏管理详解及分析

一. 方法概述

在api 18前可以通过辅助功能’AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED’或是反射活取通知栏相关信息。
现在我们可以根据NotificationListenerService类非常容易的活取通知回调相关信息。

二. NotificationListenerService详解

通知的新增和删除,都会回调你注册的NLS里的方法,这些信息可以通过StatusBarNotification类对象来获取。
另外比较主要的是,系统开启通知读取服务后,系统就会对APP有个保活功能,当被系统或是第三方软件kill后,系统会将你的应用重启。很多厂商会利用这点做一些坏坏的事情。并且国内各大杀毒,清理软件都有开启该功能。

NotificationListenerService主要方法(成员变量):

删除通知时会回调onNotificationRemoved, 新增通知或是更新时会回调onNotificationPosted

  • cancelAllNotifications() :删除系统中所有 可被清除 的通知;
  • cancelNotification(String pkg, String tag, int id) :删除具体某一个通知;
  • getActiveNotifications() :返回当前系统所有通知到StatusBarNotification[]的列表;
  • onNotificationPosted(StatusBarNotification sbn) :当系统收到新的通知后出发回调;
  • onNotificationRemoved(StatusBarNotification sbn) :当系统通知被删掉后出发回调;

StatusBarNotification类详解

StatusBarNotification,多进程传递对象,所有通知信息都会在这个类中通过Binder传递过来.
内部几个重要的方法如下:

  • getId():返回通知对应的id;
  • getNotification():返回通知对象;
  • getPackageName():返回通知对应的包名;
  • getPostTime():返回通知发起的时间;
  • getTag():返回通知的Tag,如果没有设置返回null;
  • isClearable():返回该通知是否可被清楚,FLAG_ONGOING_EVENT、FLAG_NO_CLEAR;
  • isOngoing():检查该通知的flag是否为FLAG_ONGOING_EVENT;

其中,我们通过getNotification()可以得到Notification对象,Notification是我们比较熟悉的类了,我们可以得到通知具体内容甚至可以还原RemoteViews到我们的本地view上。

三. 使用方法

正确使用NotificationListenerService需要进行三步骤:

1. 新建一个类并继承自NotificationListenerService,override其中重要的两个方法;

public class NLService extends NotificationListenerService {@Overridepublic void onNotificationPosted(StatusBarNotification sbn) {}@Overridepublic void onNotificationRemoved(StatusBarNotification sbn) {}}

2. 在AndroidManifest.xml中注册Service并声明相关权限;

   <service android:name=".NLService"android:label="@string/service_name"android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"><intent-filter><action android:name="android.service.notification.NotificationListenerService" /></intent-filter></service>

3. 开启NotificationMonitor的监听功能;

if (!isEnabled()) {Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");startActivity(intent);} else {Toast.makeText(this, "已开启服务权限", Toast.LENGTH_LONG).show();}
private boolean isEnabled() {String pkgName = getPackageName();final String flat = Settings.Secure.getString(getContentResolver(),ENABLED_NOTIFICATION_LISTENERS);if (!TextUtils.isEmpty(flat)) {final String[] names = flat.split(":");for (int i = 0; i < names.length; i++) {final ComponentName cn = ComponentName.unflattenFromString(names[i]);if (cn != null) {if (TextUtils.equals(pkgName, cn.getPackageName())) {return true;}}}}return false;}

四. Demo讲解

根据以上步骤,已经可以接收到通知栏变换时的回调,及获取当前所有通知列表,我们限制写个小例子,活取所有通知列表并且监听通知栏的变换,把收到的Notification及相关信息展示到我们的页面ListView中.

1. 按照以上步骤建立基本例子框架

写布局,要有开启服务的btn, 活取所有通知的btn和清除所有列表的btn, 界面比较简陋,如图:

2. 建立BroadcastReceiver和Service交互

当然也可以用binder说是message通信,根据自己程序设计选择,这里为了简单的演示用了BroadcastReceiver机制

class NotificationReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String temp = mInfoList.size() + ":" + intent.getStringExtra(EVENT);NTBean bean = new NTBean();bean.info = temp;Bundle budle = intent.getExtras();bean.title = budle.getString(Notification.EXTRA_TITLE);bean.text = budle.getString(Notification.EXTRA_TEXT);bean.subText = budle.getString(Notification.EXTRA_SUB_TEXT);bean.largeIcon = budle.getParcelable(Notification.EXTRA_LARGE_ICON);Icon icon = budle.getParcelable(Notification.EXTRA_SMALL_ICON);bean.smallIcon = icon;bean.viewS = budle.getParcelable(VIEW_S);bean.viewL = budle.getParcelable(View_L);mInfoList.add(bean);Log.e("changxing", "receive:" + temp + "\n" + budle);mAdapter.notifyDataSetChanged();}}

3. 活取相关回调展示页面

将回调的相关参数传递到activity中, 展示到listview中,其中可以直接用RemoteViews#apply方法将Notification展示到我们本地ViewGroup中.

程序运行如下:

程序源码地址

Github 源码地址

有兴趣的同学可以下载源码继续学习,也可以对文章的DEMO源码优化提交Pull Requests!

安卓通知栏管理详解及分析 NotificationListenerService相关推荐

  1. php事件和行为,Yii框架组件和事件行为管理详解

    Yii框架组件和事件行为管理详解 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  Yii框架组件和事件行为管理详解.txt ] (友情提示:右键点上行txt文档名- ...

  2. WebSocket安卓客户端实现详解(一)–连接建立与重连

    http://blog.csdn.net/zly921112/article/details/72973054 前言 这里特别说明下因为WebSocket服务端是公司线上项目所以这里url和具体协议我 ...

  3. Linux用户管理详解大结局(下)

    Linux用户管理详解(下) 我们已经可以通过创建不同的用户来防止其他人使用自己的账号,之后每个账户对应一个单独的用户密码,构成了一个基本的用户管理思路.为了方便管理还可以使用组来设置相同属性的用户. ...

  4. [OHIF-Viewers]医疗数字阅片-医学影像-Module: Panel-自定义面板-中二-Reduxreact-redux状态管理详解...

    [OHIF-Viewers]医疗数字阅片-医学影像-Module: Panel-自定义面板-中二-Redux&react-redux状态管理详解 先上官方文档,推荐阅读英文原版文档,是最新.最 ...

  5. x264 代码重点详解 详细分析

    eg mplayer x264 代码重点详解 详细分析 分类: ffmpeg 2012-02-06 09:19 4229人阅读 评论(1) 收藏 举报 h.264codecflv优化initializ ...

  6. Spark 内存管理详解(下):内存管理

    本文转自:Spark内存管理详解(下)--内存管理 本文最初由IBM developerWorks中国网站发表,其链接为Apache Spark内存管理详解 在这里,正文内容分为上下两篇来阐述,这是下 ...

  7. Linux操作系统的进程管理详解

    Linux操作系统的进程管理详解 pkill & pgrep pkill & pgrep 是两个很方便的命令.省去了要先ps auwx | grep xxxx然后再根据pid kill ...

  8. 基于Kubernetes构建Docker集群管理详解

    from: 基于Kubernetes构建Docker集群管理详解 Kubernetes是Google开源的容器集群管理系统,基于Docker构建一个容器的调度服务,提供资源调度.均衡容灾.服务注册.动 ...

  9. Linux账号和权限管理详解(超详细示例操作)!

    Linux账号和权限管理详解 一.用户账号和组账号概述 1.1 Linux基于用户身份对资源访问进行控制 1.2 用户账号 1.3 组账号 二.用户账号文件 2.1 用户账号文件 /etc/passw ...

最新文章

  1. python对象模型 ruby_使用JRuby/Jython实现Ruby/Python的互操作性?
  2. 累加结合律,交换律,分配律的一个例子
  3. android 自定义核心服务
  4. java网络流传输,中文乱码问题。
  5. mysql主从切换gtid不一致_解决mysql使用GTID主从复制错误问题
  6. python关闭文件os_如何关闭使用os.startfile(),Python 3.6打开的文件
  7. 上海交通大学2006年数学分析考研试题
  8. 005-JQuery之CSS
  9. 2021高考成绩查询内蒙时间,2021内蒙古高考成绩什么时候几点可以查
  10. 中文分词--词典分词--最长匹配
  11. JSR 303 - Bean Validation与Hibernate Validation 介绍
  12. 【转】第7篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:全自动注册与反射方法分析...
  13. 是可改写的随机存储器_PPT下载:磁阻随机存取存储器
  14. 禁止logback输出状态信息
  15. UltraCompare 21 for Mac(mac文本对比工具)
  16. web中间件应用系列:负载均衡(二)负载均衡算法和常见实现方式
  17. Android设置沉浸式
  18. Java开发-日期与时间戳转换封装工具类
  19. 想想自己如果不做开发,可能会从事什么职业?
  20. 计算机专业术语大全,计算机专业名词总汇,计算机专业名词总汇

热门文章

  1. 研究Xposed相关一:Xposed框架的安装
  2. 计算机中的 属性 英语怎么说,关于计算机属性的英语以及命令
  3. 关于strcmp与strcpy函数的相关用法
  4. 暨南大学计算机研究生复试机试历年真题
  5. 2022 OpenCV人工智能竞赛优秀项目团队介绍集锦(一)
  6. 涉密磁介质数据清除工具
  7. 【象形法】26个英语字母象形与90词…
  8. APOC自定义函数和过程
  9. 计算机网络之性能指标
  10. 第一章 初遇App冷启动