当前位置:网站首页>systemui屏蔽通知栏
systemui屏蔽通知栏
2022-08-10 14:29:00 【纵容_伊人倩影】
背景描述
客户说要屏蔽掉某个应用里的通知,但是不全部屏蔽,只屏蔽指定应用的部分通知。
很奇怪,这个东西要系统来做,应用不发通知不就好了嘛?
但是没办法,甲方爸爸的需求,唉(:
需求实现
方案1 ------ systemui中屏蔽通知
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java的shouldFilterOut方法中添加过滤
/** * "packageName/channelId" * 表示 包名中此channelID的通知可以显示,其它全部屏蔽,判断逻辑见{@link notificationHide} * */
private static void initNotificationFilterList(){
notificationFilterList.add("com.aaa.bbb/background_download");
notificationFilterList.add("com.aaaa.ccc/background__upgrade");
}
/** * @return true/false 标时指定同时是否需要隐藏 * @param key 指定应用的包名 * @param channelId 显示指定的通知,其它通知全部过滤 * */
public static boolean notificationHide(String key,String channelId){
if (notificationFilterList.size() == 0){
initNotificationFilterList();
}
if (key != null && key.length() > 0 && channelId != null && channelId.length() > 0){
for (int i=0;i < notificationFilterList.size();i++){
String index = notificationFilterList.get(i);
String packageName ;
String cId ;
if (index != null && index.length() > 0){
String[] dex = index.split("/");
if (dex !=null && dex.length == 2){
packageName = dex[0];
cId = dex[1];
if (key.contains(packageName)
&& !channelId.equals(cId)) {
return true;
}
}
}
}
}
return false;
}
/** * @return true if the provided notification should NOT be shown right now. */
public boolean shouldFilterOut(NotificationEntry entry) {
final StatusBarNotification sbn = entry.getSbn();
...
if (sbn != null){
if (notificationHide(sbn.getKey(),sbn.getNotification().getChannelId())){
//屏蔽应用通知
return true;
}
}
...
return false;
}
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java的onNotificationPosted中
@Override
public void onNotificationPosted(final StatusBarNotification sbn,
final RankingMap rankingMap) {
if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
if (sbn != null){
//屏蔽应用通知
if (NotificationFilter.notificationHide(sbn.getKey(),sbn.getNotification().getChannelId())){
return ;
}
}
if (sbn != null && !onPluginNotificationPosted(sbn, rankingMap)) {
mMainHandler.post(() -> {
processForRemoteInput(sbn.getNotification(), mContext);
for (NotificationHandler handler : mNotificationHandlers) {
handler.onNotificationPosted(sbn, rankingMap);
}
});
}
}
上述方法可以屏蔽systemui下面的通知,实现指定应用只显示指定通知,其它通知全部隐藏的需求。
but
这个效果只是不显示通知,通知本身还是在的。
1、比如launcher的通知小圆点,长按桌面图标的通知显示等问题。
frameworks/base/core/java/android/service/notification/NotificationListenerService.java
的getActiveNotifications方法获取通知。
2、其它应用可以通过
frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java的getNotificationRecord、getActiveNotificationsFromListener或者其他方法获取通知内容。
换个思路重新触发
我们应该从根本上删除那些要屏蔽的通知,或者从一开始就不让它add到NotificationManagerService中去。
方案2 ------ framework中屏蔽
frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java中
通知的获取主要在
@GuardedBy("mNotificationLock")
final ArrayList<NotificationRecord> mNotificationList = new ArrayList<>();
@GuardedBy("mNotificationLock")
final ArrayMap<String, NotificationRecord> mNotificationsByKey = new ArrayMap<>();
这两个列表和map中存储。我们要实现阻断添加,实现屏蔽特定通知。
1、跟踪上面2个add和put数据的地方
2、PostNotificationRunnable的run方法中进行add和put通知数据
3、EnqueueNotificationRunnable中启动的PostNotificationRunnable
4、enqueueNotificationInternal方法中启动EnqueueNotificationRunnable,但是后续发现还有其他地方也启用了EnqueueNotificationRunnable。
所以我们在enqueueNotificationInternal和EnqueueNotificationRunnable 2个地方都加了一些屏蔽处理。
void enqueueNotificationInternal(...){
...
if (notificationHide(pkg,channelId)){
//过滤通知
return;
}
if (channel == null) {
final String noChannelStr = "No Channel found for "
}
...
}
内部类EnqueueNotificationRunnable的run方法中
public void run() {
...
if (contextId != null) {
(new SnoozeNotificationRunnable(r.getSbn().getKey(),
0, contextId)).snoozeLocked(r);
return;
}
//屏蔽通知
if(r != null && r.getSbn() !=null && r.getSbn().getNotification() !=null){
String key = r.getSbn().getKey();
String channelId = r.getSbn().getNotification().getChannelId();
if (notificationHide(key,channelId)){
return;
}
}
mEnqueuedNotifications.add(r);
...
}
这样修改之后,就可以完全屏蔽,通知不会添加到列表中了。
结尾
上述流程只是notification通知流程中的一小部分
完整的通知发送----framework添加通知----systemui显示通知。等流程没有完全跟踪。
如果有理解不到位的地方,欢迎留言~
补充
通知的使用:https://blog.csdn.net/jppipai/article/details/122864465
1、应用发送通知------framework中service管理通知数据
NotificationManager.notify------NotificationManagerService.enqueueNotificationWithTag------NotificationManagerService.enqueueNotificationInternal
这里就和上面service屏蔽通知的地方呼应上了。
//manager作为给上层的接口,最终还是会掉到service管理通知数据
frameworks/base/core/java/android/app/NotificationManager.java
public void notify(int id, Notification notification)
{
notify(null, id, notification);
}
public void notify(String tag, int id, Notification notification)
{
notifyAsUser(tag, id, notification, mContext.getUser());
}
public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
{
INotificationManager service = getService();
String pkg = mContext.getPackageName();
try {
if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
fixNotification(notification), user.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
//service管理通知数据
frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java
@Override
public void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,
Notification notification, int userId) throws RemoteException {
enqueueNotificationInternal(pkg, opPkg, Binder.getCallingUid(),
Binder.getCallingPid(), tag, id, notification, userId);
}
边栏推荐
猜你喜欢

无线网络、HTTP缓存、IPv6

MySQL - storage engine for databases

符合信创要求的堡垒机有哪些?支持哪些系统?

系统架构系列文章三--解决传统企业核心系统的性能问题

“Oracle 封禁了我的账户”

普林斯顿微积分读本05第四章--求解多项式的极限问题

缺少比较器,运放来救场!(运放当做比较器电路记录)

2022年网络安全培训火了,缺口达95%,揭开网络安全岗位神秘面纱

Error: Rule can only have one resource source (provided resource and test + include + exclude)

Do not access Object.prototype method ‘hasOwnProperty‘ from target object....
随机推荐
2022年网络安全培训火了,缺口达95%,揭开网络安全岗位神秘面纱
PHP judges whether the file has content, and if there is no content, copy another file to write
奢侈品鉴定机构小程序开发制作功能介绍
文件系统设计
从全球价值链视角看,京东云数智供应链对未来经济有何影响?
领域驱动模型设计与微服务架构落地-从项目去剖析领域驱动
Data product manager thing 2
PyTorch multi-machine multi-card training: DDP combat and skills
file system design
MySQL interview questions
In the second half of 2012 system architecture designers afternoon paper II
王学岗—————————哔哩哔哩直播-手写哔哩哔哩硬编码录屏推流(硬编)(26节课)
兆骑科创创业赛事活动发布平台,创业赛事,项目路演
Alibaba的秒杀系统—千亿级并发设计手册上线了
注意力模型---Attention Model
波士顿房价预测
leetcode 739. Daily Temperatures 每日温度(中等)
How to code like a pro in 2022 and avoid If-Else
易观分析联合中小银行联盟发布海南数字经济指数,敬请期待!
数据产品经理那点事儿 一