zoukankan      html  css  js  c++  java
  • 【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路径为
    frameworksaseservicesjavacomandroidserverNotificationManagerService.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值。否则easy出现点击重新启动的状况。改动后代码例如以下。

    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;
            }
    

    这里写图片描写叙述
    最后的实现结果

  • 相关阅读:
    Hdu-5983 2016ACM/ICPC亚洲区青岛站 B.Pocket Cube 模拟
    Codeforces Round #300 F
    cf298F:状压dp+剪枝
    POJ3294--Life Forms 后缀数组+二分答案 大于k个字符串的最长公共子串
    jzp线性筛及其简单应用
    Codeforces Round #299 (Div. 1)C. Tavas and Pashmaks (凸壳)
    Codeforces Round #236 (Div. 2)E. Strictly Positive Matrix(402E)
    【2012天津区域赛】部分题解 hdu4431—4441
    HDU4436---str2int 后缀树组(12年天津区域赛)
    Codeforces
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/7182093.html
Copyright © 2011-2022 走看看