当前位置:网站首页>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);
}
边栏推荐
猜你喜欢
随机推荐
NAACL 2022 | 简单且高效!随机中间层映射指导的知识蒸馏方法
线上线下课程教学培训小程序开发制作功能介绍
Send a post request at the front desk can't get the data
数据产品经理那点事儿 一
BCG库简介
In the second half of 2012 system architecture designers afternoon paper II
leetcode 739. Daily Temperatures 每日温度(中等)
Vivado crashes or the message is not displayed
物资采购小程序开发制作功能介绍
numpy.meshgrid()理解
1004 (tree array + offline operation + discretization)
文件系统设计
【POI 2008, BLO】Cut Point
2022-08-10日报: Swin Transformer作者曹越加入智源,开展视觉基础模型研究
2012年下半年 系统架构设计师 下午试卷 II
网络安全(加密技术、数字签名、证书)
Error: Rule can only have one resource source (provided resource and test + include + exclude)
data product manager
简单的写一个防抖跟节流
Parallels 将扩展桌面平台产品,以进一步改善在 Mac 上运行 Windows 的用户体验和工作效率