【Notification】屏蔽特定应用的通知提示

需要默认屏蔽特定app的通知提示

设置app是否接收通知的界面

点击每个条目进去的界面

AppNotificationSettings extends SettingsPreferenceFragment
private SwitchPreference mBlock; //条目通过Preference设置
mBlock.setChecked(mAppRow.banned);

mBlock.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
    final boolean block = (Boolean) newValue;
    return mBackend.setNotificationsBanned(pkg, uid, block);
}
    });

    // Users cannot block notifications from system/signature packages
    //通过工具类判断app是系统包(如计算器)时移除设置通知设置的preference
    if (Utils.isSystemPackage(pm, info)) {
        getPreferenceScreen().removePreference(mBlock);
        mPriority.setDependency(null); // don‘t have it depend on a preference that‘s gone
    }

通过对Block的当前状态通过mAppRow设置

对preference状态的监听,通过mBackend实现

import com.android.settings.notification.NotificationAppList.AppRow;

import com.android.settings.notification.NotificationAppList.Backend;

查看NotificationAppList.java

    //对AppRow中的属性进行初始化
    public static AppRow loadAppRow(PackageManager pm, ApplicationInfo app,
            Backend backend) {
        final AppRow row = new AppRow();
        row.pkg = app.packageName;
        row.uid = app.uid;
        try {
            row.label = app.loadLabel(pm);
        } catch (Throwable t) {
            Log.e(TAG, "Error loading application label for " + row.pkg, t);
            row.label = row.pkg;
        }
        row.icon = app.loadIcon(pm);
        row.banned = backend.getNotificationsBanned(row.pkg, row.uid);// 是否禁止通知
        row.priority = backend.getHighPriority(row.pkg, row.uid);
        row.sensitive = backend.getSensitive(row.pkg, row.uid);
        return row;
}

查看INotificationManager接口

find frameworks/ -name “INotification*”

frameworks/support/v4/java/android/support/v4/app/INotificationSideChannel.aidl

frameworks/base/core/java/com/mediatek/common/mom/INotificationListener.aidl

frameworks/base/core/java/android/app/INotificationManager.aidl

frameworks/base/core/java/android/service/notification/INotificationListener.aidl

.aidl文件(接口定义语言,用于进程间通讯)

frameworks/base/core/java/android/app/INotificationManager.aidl

实现的service路径为

frameworks\base\services\java\com\android\server\NotificationManagerService.java

对接受Notification属性的获取

mService的类型IAppOpsService

frameworks/base/core/java/com/android/internal/app/IAppOpsService.aidl

frameworks/base/services/core/java/com/android/server/AppOpsService.java

返回的值为MODE_IGNORED时,boolean areNotificationsEnabledForPackage(String pkg, int uid)会返回false

mService.checkOperation(op, uid, packageName) = MODE_ALLOWED时,则允许接收通知 ;

对接受Notification的属性设置

@Override
        public void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) {
            checkCallerIsSystem();

            setNotificationsEnabledForPackageImpl(pkg, uid, enabled);
        }

AppOpsManager的路径:frameworks/base/core/java/android/app/AppOpsManager.java

public static final int OP_POST_NOTIFICATION = 11;

uid = app.uid

pkg = app.packageName;

mode = enabled?AppOpsManager.MODE_ALLOWED:AppOpsManager.MODE_IGNORED

查看代码中哪些位置调用了setNotificationsEnabledForPackageImpl方法

除此处还有两处都是对方法的重写与具体实现

具体解决步骤

当需要屏蔽所有应用通知没有例外时

在AppOpsManager中有关于app许多参数设置的默认值,比如图中第十二个就是默认对app的通知开启或关闭,AppOpsService中的checkOperation方法下就进行了判断,当op为空时,返回的时默认的MODE。所以讲原本的MODE_ALLOWED改为MODE_IGNORED后,编译frameworks/base后push进手机重启就会发现所有app全部被屏蔽通知没有例外。当有特定的app需要开启通知时,我们可以在checkOperation中进行修改。

   @Override
    public int checkOperation(int code, int uid, String packageName) {
        verifyIncomingUid(uid);
        verifyIncomingOp(code);
        synchronized (this) {
            if (isOpRestricted(uid, code, packageName)) {
                return AppOpsManager.MODE_IGNORED;
            }
            Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false);
            if (op == null) {
                return AppOpsManager.opToDefaultMode(code);
            }
            return op.mode;
        }
}

在checkOperation中进行判断时需要判断code值,否则容易出现点击重启的状况,修改后代码如下。

public int checkOperation(int code, int uid, String packageName) {
        verifyIncomingUid(uid);
        verifyIncomingOp(code);
        synchronized (this) {
         //chenzilong add for ZELY-41 block app notifications 20160331 start
         if(code == AppOpsManager.OP_POST_NOTIFICATION){
             if ((packageName.equals("com.advan.advanstore")||packageName.equals("com.stkj.android.freeshare"))){
                 return AppOpsManager.MODE_ALLOWED;
             }else{
                 return AppOpsManager.MODE_IGNORED;
             }
         }
         // chenzilong add for ZELY-41 block app notifications 20160331 end

            if (isOpRestricted(uid, code, packageName)) {
                return AppOpsManager.MODE_IGNORED;
            }
            Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false);
            if (op == null) {
                return AppOpsManager.opToDefaultMode(code);
            }
            return op.mode;
        }

最后的实现结果

时间: 2024-10-13 08:45:48

【Notification】屏蔽特定应用的通知提示的相关文章

使用Notification在状态栏上显示通知

运行效果图:              结构目录: 注意事项: 如果logcat有错误提示:No Channel found for pkg, 可参考链接:https://blog.csdn.net/u010356768/article/details/83546008 activity_main.xml: 1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:androi

IOS 新消息通知提示-声音、震动

一.APNS 1.注册 [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert];复制代码2.服务器推送(JAVA) PushNotificationPayload payLoad =  PushNotificationPayl

toastr 通知提示插件

table.sb-tb td,table.sb-tb th { padding: 5px 10px !important } jquery toastr 一款轻量级的通知提示框插件. 网页开发中经常会用到提示框,自带的alert样式无法调整,用户体验差. 所以一般通过自定义提示框来实现弹窗提示信息,而jquery toastr正是为此的一款非常棒的插件. 开发中用angular比较多,所以笔记记录了angular一些常见使用,与jquery版本有些许不同 ,相差不大. 在HTML引用js文件 <

应用 CSS3 动画实现12种风格的通知提示

今天我们想分享几个简单的款式的网站通知效果.有很多的方式来呈现消息给用户:从经典的咆哮般的通知到窗口顶部的通知栏.各个网站的通知样式和效果千篇一律,难得出现创意的通知效果.这里是实现一个应用 CSS3 动画实现各种风格的通知提示. 在线演示      立即下载 您可能感兴趣的相关文章 网站开发中很有用的 jQuery 效果[附源码] 分享35个让人惊讶的 CSS3 动画效果演示 十分惊艳的8个 HTML5 & JavaScript 特效 Web 开发中很实用的10个效果[源码下载] 12款经典的

漂亮灵活设置的jquery通知提示插件toastr

toastr是一款非常棒的基于jquery库的非阻塞通知提示插件,toastr可设定四种通知模式:成功,出错,警告,提示,而提示窗口的位置,动画效果都可以通过能数来设置,在官方站可以通过勾选参数来生成JS,非常的方便使用.jQ酷的另外一款jquery提示插件也不错:jQuery自定义工具提示插件DarkTooltip. 使用方法: 引入核心文件 1 2 3 <link href="toastr.css" rel="stylesheet" type="

nginx,apache屏蔽特定路径下的php,python解析

工作中碰到一些目录需要写入数据,为了安全起见需要屏蔽特定路径下的php,python解析. nginx相关配置: location ~/(data|sites/upload)/.*\.(php|php5|py|pyc|sh)?$ { deny all; } apache相关配置: <Directory /usr/local/apache/htdocs/bbs/data> php_flag engine off </Directory> <Directory ~ "^

iPhone屏蔽IOS9、IOS10更新提示(免越狱)

1.在Safari浏览器中粘贴如下链接,按提示打开链接. 输入http://apt.chenzhe.me 2.打开链接,按提示输入密码,安装描述文件,提示签名,重启设备. 3.重启之后桌面多出了一个Feedback(反馈助手),不用管它. 4.以后如果想通过OTA在线更新系统时,在设置-通用-描述文件-删除tvOS 10 Beta …. 备注: 此方式能屏蔽系统更新,设置-软件更新那里的小红点不越狱我还没办法消除.

Android中使用Notification在状态栏上显示通知

场景 状态栏上显示通知效果 注: 博客: https://blog.csdn.net/badao_liumang_qizhi关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 新建NotificationActivity,通过getSystemService方法获取通知管理器. 然后创建通知并设置通知的一些属性,再使用通知管理器发送通知. package com.badao.relativelayouttest; import androidx.annotation.Req

javascript 替换浏览器Tab的title实现消息通知提示

实现逻辑:1. 创建两个互调用函数 setTitle1和setTitle22. 定时调用机制3. 窗体获取焦点和失去焦点存状态4. 来消息了存状态(在本例中,模拟每3秒来1个消息)5. 在setTitle1中判断状态 完整代码: <script src="jquery-1.10.2.js" ></script> <div class="pnl"></div> <script> var newMsg = fa