当前位置: 首页 > news >正文

Android通知监听服务之NotificationListenerService使用篇

前言

本篇我们将介绍如何利用NotificationListenerService实现类似智能手表通知同步、微信自动抢红包等功能。实现这些功能的原理其实就是监听系统的通知服务,接下来我们来看该如何实现。

NotificationListenerService的使用

创建NotificationListenerService

在Android中如果我们想要监听系统的通知,就需要实现一个服务,继承自NotificationListenerService,新建NotificationMonitorService类,代码如下所示。

class NotificationMonitorService : NotificationListenerService() {
    //收到通知时的回调
    override fun onNotificationPosted(sbn: StatusBarNotification) {
        super.onNotificationPosted(sbn)
    }

    //通知移除时的回调
    override fun onNotificationRemoved(sbn: StatusBarNotification?) {
        super.onNotificationRemoved(sbn)
    }
}

这里我们重写onNotificationPosted方法和onNotificationRemoved方法,这两个方法分别会在收到通知和通知被移除时调用。这里我们着重来看onNotificationPosted方法。

在onNotificationPosted方法中有一个StatusBarNotification实例,通过这个实例我们可以获取通知消息的包名、内容等。代码如下所示。

class NotificationMonitorService : NotificationListenerService() {
    override fun onNotificationPosted(sbn: StatusBarNotification) {
        super.onNotificationPosted(sbn)
        val extras = sbn.notification.extras
        // 获取接收消息APP的包名
        val notificationPkg = sbn.packageName
        // 获取接收消息的抬头
        val notificationTitle = extras.getString(Notification.EXTRA_TITLE)
        // 获取接收消息的内容
        val notificationText = extras.getString(Notification.EXTRA_TEXT)
        Log.d("收到的消息内容包名:", notificationPkg)
        Log.d("收到的消息内容", "Notification posted $notificationTitle & $notificationText")
    }
}

然后记得在配置文件中添加这个Service的声明,代码如下所示。

<service android:name="com.example.myapplication.NotificationMonitorService"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
    android:exported="true">
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>

创建好NotificationMonitorService之后,接下来我们就可以启动这个服务了。

启动服务

现在直接启动服务,肯定是没办法监听到系统通知的,在启动服务前,我们应该授予App监听系统通知的权限。

在AndroidManifest.xml中添加权限,代码如下所示。

 <uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>

启动服务前判断是否开启了监听通知的权限,如果没有则跳转到设置页开启,代码如下所示。

if (NotificationManagerCompat.getEnabledListenerPackages(this).contains(packageName)){
    val intent = Intent(this,NotificationMonitorService::class.java)
    startService(intent)
 }else{
    startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))
 }

如果没有开启,跳转到的设置页如下所示。

开启了监听通知权限,运行程序,打印日志如下所示。

 对应的打印日志是,收到了来自微信的群聊消息,发了一个“强”。

当收到短信、来电等消息时,系统同样会发送一个通知,我们可以根据收到的通知处理不同的业务。这里感兴趣的读者可自行尝试。接着我们来模拟实现自动抢红包的功能。

实现自动抢红包功能

这里为了测试,历尽千辛万苦让我老婆给我发了一个0.01的红包,我们监听到的内容为“[微信红包]恭喜发财,大吉大利”。如下图所示。

 所以我们可以在收到消息时,通过监听微信包名、以及消息内容来判断是否收到了微信红包来处理具体的操作。(不处理,别人故意发同样的文字)。

if (notificationPkg.equals("com.tencent.mm")){
   if (notificationText.equals("[微信红包]恭喜发财,大吉大利")){
      //收到微信红包了
   }
}

这样我们只需要在代码处处理接下来的操作就可以了。其实我们的操作也很简单,只需要在监听到有红包时打开对应的微信页面即可,代码如下所示。

class NotificationMonitorService : NotificationListenerService() {
    override fun onNotificationPosted(sbn: StatusBarNotification) {
        super.onNotificationPosted(sbn)
        val extras = sbn.notification.extras
        // 获取接收消息APP的包名
        val notificationPkg = sbn.packageName
        // 获取接收消息的内容
        val notificationText = extras.getString(Notification.EXTRA_TEXT)
        if (notificationPkg.equals("com.tencent.mm")){
            if (notificationText.equals("[微信红包]恭喜发财,大吉大利")){
                //收到微信红包了
                val intent = sbn.notification.contentIntent
                intent.send()
            }
        }
    }
}

这里我们直接通过sbn拿到notification的intent,进行intent.send操作即可,运行程序,收到红包后,页面将自动跳转到微信红包页面,结果如下图所示。

写在最后

利用通知监听服务这一功能,我们可以实现许多诸如 智能手表的消息同步、微信抢红包等功能,如果你有需要,也可以让你女朋友的消息立即弹出,这样就再也不用跪搓衣板啦~

下一篇我们将着重深挖监测通知服务的原理,下一篇见~

相关文章:

  • java编程计算机网页项目jsp高校体育竞技赛系统myeclipse开发Mysql数据库web结构
  • 【前端】Vue+Element UI案例:通用后台管理系统-导航栏
  • 【线性代数】三、特征值和特征向量
  • 基于 BP 神经网络特征提取的指纹识别应用(Matlab代码实现)
  • 渗透测试CTF-图片隐写的详细教程(干货)
  • 全栈性能测试详解
  • 子网掩码的作用是什么?VLSM又是怎么实现的
  • string类详解
  • Yolov5:强大到你难以想象──新冠疫情下的口罩检测
  • 四大含金量高的算法证书考试
  • 前端小游戏——植物大战僵尸
  • 网鼎杯网络安全大赛玄武组-SSRFME
  • 【计算机组成原理】第二章单元测试
  • 仿黑马点评-redis整合【二——商户查询缓存】——缓存穿透、缓存击穿的解决
  • 如果再来一次,你还会选择互联网么?
  • 深入了解以太坊
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • MYSQL 的 IF 函数
  • Python打包系统简单入门
  • React-生命周期杂记
  • Redis 中的布隆过滤器
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • supervisor 永不挂掉的进程 安装以及使用
  • Vim Clutch | 面向脚踏板编程……
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 如何合理的规划jvm性能调优
  • 协程
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • Python 之网络式编程
  • Semaphore
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​香农与信息论三大定律
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #Spring-boot高级
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • (2)(2.10) LTM telemetry
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (一)appium-desktop定位元素原理
  • (转)拼包函数及网络封包的异常处理(含代码)
  • .form文件_一篇文章学会文件上传
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .net core 控制台应用程序读取配置文件app.config
  • .Net Web项目创建比较不错的参考文章
  • .NET 事件模型教程(二)
  • .net/c# memcached 获取所有缓存键(keys)
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .NET连接数据库方式
  • .NET微信公众号开发-2.0创建自定义菜单
  • /dev/VolGroup00/LogVol00:unexpected inconsistency;run fsck manually