Android 12.0 应用中监听系统收到的通知

2024-02-01 11:52

本文主要是介绍Android 12.0 应用中监听系统收到的通知,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android 12.0 通知简介icon-default.png?t=N7T8https://blog.csdn.net/Smile_729day/article/details/135502031?spm=1001.2014.3001.5502 

1. 需求

在系统内置应用中或者在第三方应用中,获取Android系统收到的通知的内容.

2. NotificationListenerService 接口

Android 系统预留了专门的API, 即 NotificationListenerService 接口,它的源码路径为:

源码路径 : /frameworks/base/core/java/android/service/notification/NotificationListenerService.javapublic abstract class NotificationListenerService extends Service {......

3. 实现 NotificationListenerService

NotificationListenerService 是抽象类,通过在 Service 中实现该抽象类,并实现需要的接口,代码如下:

public class MyNotificationListenerService extends NotificationListenerService {//当系统收到新的通知时,会触发该接口@Overridepublic void onNotificationPosted(StatusBarNotification sbn) {addAlienNotificationInfo(sbn); //获取通知的内容}//当系统移除通知时,即在通知列表中清除通知时,或者卸载应用时,该应用包名下的通知都会被清除,也同样会会触发该接口@Overridepublic void onNotificationRemoved(StatusBarNotification sbn) {super.onNotificationRemoved(sbn);}
}

上面两个接口,第一个是监听系统新通知,第二个是监听系统通知清除,如果看过Android Systemui 中有关通知的内容,就会发现,System UI 对通知的显示和通知的清除,同样也是继承该API.

下面,分析当系统收到新通知时,如何解析出通知里的内容.

4. 获取通知内容

   private void addAlienNotificationInfo(StatusBarNotification sbn) {String packageName = sbn.getPackageName();//获取发送通知的包名Notification notification = sbn.getNotification(); //获得一个Notification对象Bundle extras = notification.extras;RemoteViews contentView = notification.contentView;//ApplicationInfo appInfo = extras.getParcelable(NotificationCompat.EXTRA_BUILDER_APPLICATION_INFO);//如果是系统内置应用,可以获取到ApplicationInfo ,后面会有解释//String appName = appInfo.loadLabel(mPm).toString(); //如果是系统内置的应用,可以通过ApplicationInfo对象获取通知发送这条通知的应用名String category = notification.category;String channelId = notification.getChannelId();//String className = getNotificationClassName(notification);//如果是系统内置应用,可以获取到通知中设置的Intent,后面会有解释int color = notification.color;//通知setColor()设置的颜色boolean defaultVibrate = (notification.vibrate == null) ? true : false;String notificationVibrationString = Arrays.toString(notification.vibrate);int importance = notification.priority; //通知的重要性String key = sbn.getKey();//通知的Key,删除通知时,需要通过Key来确定删除哪条通知Icon myLargeIconToIcon = extras.getParcelable(Notification.EXTRA_LARGE_ICON);//获取通知设置的大图片,即setLargeIcon() ,int ledColor = notification.ledARGB;//通知led灯颜色String sound = (notification.sound != null) ? notification.sound.toString() : null;int progress = extras.getInt(Notification.EXTRA_PROGRESS);//当前进度值int progressMax = extras.getInt(Notification.EXTRA_PROGRESS_MAX);//设定的最大进度值boolean progressIndeterminate = extras.getBoolean(Notification.EXTRA_PROGRESS_INDETERMINATE);//是否在通知中显示进度值int flagsToCheck = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;boolean resident = (notification.flags & flagsToCheck) != 0;//是否是常驻通知(前台&onging),类似于音乐应用,String smallIcon = notification.getSmallIcon().toString();//通知设置的smallIcon()String title = (String) extras.get(Notification.EXTRA_TITLE);//通知标题String subText = (String) extras.get(Notification.EXTRA_SUB_TEXT);//通知附加内容String text = (String) extras.get(Notification.EXTRA_TEXT);//通知内容boolean userRemovable = (notification.flags & Notification.FLAG_AUTO_CANCEL) != 0; //是否可移除通知,即 setAutoCancel(boolean autoCancel) 中设定的值long when = notification.when;//通知的时间String template = getNotificationTemplate(notification);//获取通知的类型,下面会详细介绍//BigTextStyle通知中,bigText的内容String bigText = (String) extras.getCharSequence(Notification.EXTRA_BIG_TEXT);    //BigPictureStyle通知中设置的大图片Bitmap picture_extraBitmap = extras.getParcelable(Notification.EXTRA_PICTURE);//状态栏通知列表中,折叠时是否显示图片,注意:该属性在Android12上有,Android11上没有,boolean mShowBigPictureWhenCollapsed = extras.getBoolean(Notification.EXTRA_SHOW_BIG_PICTURE_WHEN_COLLASED);//通过下面的方法也可以查看通知中的设置的全部参数for(String mykey : notification.extras.keySet()){String ex = " " + mykey +" => " + notification.extras.get(mykey)+ ";";Log.d(TAG,"ex="+ex);}
}

(1) 获取ApplicationInfo

      上面在获取通知的ApplicationInfo时,使用了 Notification.EXTRA_BUILDER_APPLICATION_INFO,该值不对系统外开放,如下源码所示:

源码路径:/frameworks/base/core/java/android/app/Notification.java/*** @hide*/public static final String EXTRA_BUILDER_APPLICATION_INFO = "android.appInfo";

(2) getNotificationClassName(notification)

        上面还涉及到了getNotificationClassName(notification) 获取这条通知中通过PendingIntent中设置的 Intent ,方法中用到了不对外使用的方法,代码如下:

 private String getNotificationClassName(Notification notification) {if (notification.contentIntent != null) {Intent intent = notification.contentIntent.getIntent();if (intent != null && intent.getComponent() != null) {return intent.getComponent().getClassName();}}return null;}

(3) 获取 PendingIntent 对象

         其中的 notification.contentIntent 是获取 通知中的 PendingIntent 对象,源码如下:

源码路径:/frameworks/base/core/java/android/app/Notification.java /*** 单击展开的状态条目时要执行的意图。*/public PendingIntent contentIntent;
(4) PendingIntent.getIntent()

         接着再通过调用 PendingIntent 对象中的 getIntent() 来获取通知中设定的 Intent, 源码如下:

源码路径: /frameworks/base/core/java/android/app/PendingIntent.java/*** @hide (该方法不对外公开)* 返回 PendingIntent 中的 Intent .*/@UnsupportedAppUsagepublic Intent getIntent() {try {return ActivityManager.getService().getIntentForIntentSender(mTarget);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}

 由于源码中有@hide,表明该方法不对第三方应用开放,所以如果是系统内置的应用,则可以使用.

(5) getNotificationTemplate(Notification notification) 

         Android中定义了一些通知模板,常用的如: BigPictureStyle , BigTextStyle 等,代码如下:

/*** 返回通知的类型,如果没有使用,则返回null.* 返回的类型,如: "android.app.Notification$BigTextStyle",* 因此需要对字符串进行截取,如最后返回: "BigTextStyle"
*/private String getNotificationTemplate(Notification notification) {String template = notification.extras.getString(Notification.EXTRA_TEMPLATE);if (template != null) {int indexOf = template.indexOf('$');return template.substring(indexOf + 1);}return null;}

5. 通知的清除 

当通知被清除时,会调用 onNotificationRemoved(StatusBarNotification sbn) 方法,其中的参数 sbn 代表被删除的通知.可以在该方法里做一些删除后的工作.

6 . NotificationListenerService 中其他有用的方法

(1) 获取有效的通知 : getActiveNotifications() 

源码路径: /frameworks/base/core/java/android/service/notification/NotificationListenerService.java/*** 请求未完成通知的列表(即那些对当前用户)。** @return 活动通知数组,按自然顺序排序。*/public StatusBarNotification[] getActiveNotifications() {StatusBarNotification[] activeNotifications = getActiveNotifications(null, TRIM_FULL);return activeNotifications != null ? activeNotifications : new StatusBarNotification[0];}

(2) 删除指定单条通知 : cancelNotification(String key)   

源码路径: /frameworks/base/core/java/android/service/notification/NotificationListenerService.java /*** 删除指定的一条通知**/public final void cancelNotification(String key) {if (!isBound()) return;//是否绑定了NotificationListenerService服务try {getNotificationInterface().cancelNotificationsFromListener(mWrapper,new String[] { key });} catch (android.os.RemoteException ex) {Log.v(TAG, "Unable to contact notification manager", ex);}}

 (3) 删除指定的多条通知: cancelNotifications(String[] keys)

源码路径: /frameworks/base/core/java/android/service/notification/NotificationListenerService.java /*** 删除 数组 keys 中指定key的通知*/public final void cancelNotifications(String[] keys) {if (!isBound()) return;try {getNotificationInterface().cancelNotificationsFromListener(mWrapper, keys);} catch (android.os.RemoteException ex) {Log.v(TAG, "Unable to contact notification manager", ex);}}

(4) 清除所有通知,对应于通知列表下的 清除所有通知的按钮功能: cancelAllNotifications()

  /*** 通知通知管理器清除所有通知* 类似于Android状态栏和通知面板调用 UI 的“全部关闭”功能* 收到通知后,通知管理器实际上会删除所有活动通知* 并且收到多个 {@link #onNotificationRemoved(StatusBarNotification)} 回调。*/public final void cancelAllNotifications() {cancelNotifications(null /*all*/);}

至此,关于监听系统通知介绍完毕,谢谢观看!

这篇关于Android 12.0 应用中监听系统收到的通知的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/667193

相关文章

线程池ThreadPoolExecutor应用过程

《线程池ThreadPoolExecutor应用过程》:本文主要介绍如何使用ThreadPoolExecutor创建线程池,包括其构造方法、常用方法、参数校验以及如何选择合适的拒绝策略,文章还讨论... 目录ThreadPoolExecutor构造说明及常用方法为什么强制要求使用ThreadPoolExec

mysql_mcp_server部署及应用实践案例

《mysql_mcp_server部署及应用实践案例》文章介绍了在CentOS7.5环境下部署MySQL_mcp_server的步骤,包括服务安装、配置和启动,还提供了一个基于Dify工作流的应用案例... 目录mysql_mcp_server部署及应用案例1. 服务安装1.1. 下载源码1.2. 创建独立

Android使用java实现网络连通性检查详解

《Android使用java实现网络连通性检查详解》这篇文章主要为大家详细介绍了Android使用java实现网络连通性检查的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录NetCheck.Java(可直接拷贝)使用示例(Activity/Fragment 内)权限要求

2025最新版Android Studio安装及组件配置教程(SDK、JDK、Gradle)

《2025最新版AndroidStudio安装及组件配置教程(SDK、JDK、Gradle)》:本文主要介绍2025最新版AndroidStudio安装及组件配置(SDK、JDK、Gradle... 目录原生 android 简介Android Studio必备组件一、Android Studio安装二、A

Nginx内置变量应用场景分析

《Nginx内置变量应用场景分析》Nginx内置变量速查表,涵盖请求URI、客户端信息、服务器信息、文件路径、响应与性能等类别,这篇文章给大家介绍Nginx内置变量应用场景分析,感兴趣的朋友跟随小编一... 目录1. Nginx 内置变量速查表2. 核心变量详解与应用场景3. 实际应用举例4. 注意事项Ng

Java中的随机数生成案例从范围字符串到动态区间应用

《Java中的随机数生成案例从范围字符串到动态区间应用》本文介绍了在Java中生成随机数的多种方法,并通过两个案例解析如何根据业务需求生成特定范围的随机数,本文通过两个实际案例详细介绍如何在java中... 目录Java中的随机数生成:从范围字符串到动态区间应用引言目录1. Java中的随机数生成基础基本随

利用Python操作Word文档页码的实际应用

《利用Python操作Word文档页码的实际应用》在撰写长篇文档时,经常需要将文档分成多个节,每个节都需要单独的页码,下面:本文主要介绍利用Python操作Word文档页码的相关资料,文中通过代码... 目录需求:文档详情:要求:该程序的功能是:总结需求:一次性处理24个文档的页码。文档详情:1、每个

Java中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例解析

《Java中的分布式系统开发基于Zookeeper与Dubbo的应用案例解析》本文将通过实际案例,带你走进基于Zookeeper与Dubbo的分布式系统开发,本文通过实例代码给大家介绍的非常详... 目录Java 中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例一、分布式系统中的挑战二

Java 缓存框架 Caffeine 应用场景解析

《Java缓存框架Caffeine应用场景解析》文章介绍Caffeine作为高性能Java本地缓存框架,基于W-TinyLFU算法,支持异步加载、灵活过期策略、内存安全机制及统计监控,重点解析其... 目录一、Caffeine 简介1. 框架概述1.1 Caffeine的核心优势二、Caffeine 基础2

使用Node.js和PostgreSQL构建数据库应用

《使用Node.js和PostgreSQL构建数据库应用》PostgreSQL是一个功能强大的开源关系型数据库,而Node.js是构建高效网络应用的理想平台,结合这两个技术,我们可以创建出色的数据驱动... 目录初始化项目与安装依赖建立数据库连接执行CRUD操作查询数据插入数据更新数据删除数据完整示例与最佳