android7.0的设置app中的通知权限设置流程

一、核心类

Settings/src/com/android/settings/applications/ManageApplications.java

Settings/src/com/android/settings/applications/InstalledAppDetails.java

Settings/src/com/android/settings/AppNotificationSettings.java

frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java

二、源码流程

(1):ManageApplications.java类中获取所有app的列表及点击事件
 @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        if (mApplications != null && mApplications.getCount() > position) {
            ApplicationsState.AppEntry entry = mApplications.getAppEntry(position);
            mCurrentPkgName = entry.info.packageName;
            mCurrentUid = entry.info.uid;
            startApplicationDetailsActivity();
        }
    }


 // utility method used to start sub activity
    private void startApplicationDetailsActivity() {
        switch (mListType) {
            case LIST_TYPE_NOTIFICATION:
                startAppInfoFragment(AppNotificationSettings.class,
                        R.string.app_notifications_title);
                break;
            case LIST_TYPE_DOMAINS_URLS:
                startAppInfoFragment(AppLaunchSettings.class, R.string.auto_launch_label);
                break;
            case LIST_TYPE_USAGE_ACCESS:
                startAppInfoFragment(UsageAccessDetails.class, R.string.usage_access);
                break;
            case LIST_TYPE_STORAGE:
                startAppInfoFragment(AppStorageSettings.class, R.string.storage_settings);
                break;
            case LIST_TYPE_HIGH_POWER:
                HighPowerDetail.show(this, mCurrentPkgName, INSTALLED_APP_DETAILS,
                        mFinishAfterDialog);
                break;
            case LIST_TYPE_OVERLAY:
                startAppInfoFragment(DrawOverlayDetails.class, R.string.overlay_settings);
                break;
            case LIST_TYPE_WRITE_SETTINGS:
                startAppInfoFragment(WriteSettingsDetails.class, R.string.write_system_settings);
                break;
            // TODO: Figure out if there is a way where we can spin up the profile's settings
            // process ahead of time, to avoid a long load of data when user clicks on a managed app.
            // Maybe when they load the list of apps that contains managed profile apps.
            default:
               startAppInfoFragment(InstalledAppDetails.class, R.string.application_info_label);
                break;
        }
    }

private void startAppInfoFragment(Class<?> fragment, int titleRes) {
        AppInfoBase.startAppInfoFragment(fragment, titleRes, mCurrentPkgName, mCurrentUid, this,
                INSTALLED_APP_DETAILS);
    }
(2):跳转对应的app详情页
startAppInfoFragment(InstalledAppDetails.class, R.string.application_info_label);函数会跳转到InstalledAppDetails.java类
 private static final String KEY_HEADER = "header_view";//
 private static final String KEY_NOTIFICATION = "notification_settings";//通知
 private static final String KEY_STORAGE = "storage_settings";//存储
 private static final String KEY_PERMISSION = "permission_settings";//权限
 private static final String KEY_DATA = "data_settings"; //流量使用
 private static final String KEY_LAUNCH = "preferred_settings";//默认打开
 private static final String KEY_BATTERY = "battery";//电池
 private static final String KEY_MEMORY = "memory";//内存


@Override
    public boolean onPreferenceClick(Preference preference) {
        if (preference == mStoragePreference) {
            startAppInfoFragment(AppStorageSettings.class, mStoragePreference.getTitle());
        } else if (preference == mNotificationPreference) {
            startAppInfoFragment(AppNotificationSettings.class,
                    getString(R.string.app_notifications_title));
        } else if (preference == mPermissionsPreference) {
            startManagePermissionsActivity();
        } else if (preference == mLaunchPreference) {
            startAppInfoFragment(AppLaunchSettings.class, mLaunchPreference.getTitle());
        } else if (preference == mMemoryPreference) {
            ProcessStatsBase.launchMemoryDetail((SettingsActivity) getActivity(),
                    mStatsManager.getMemInfo(), mStats, false);
        } else if (preference == mDataPreference) {
            startAppInfoFragment(AppDataUsage.class, getString(R.string.app_data_usage));
        } else if (preference == mBatteryPreference) {
            BatteryEntry entry = new BatteryEntry(getActivity(), null, mUserManager, mSipper);
            PowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
                    mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry, true, false);
        } else {
            return false;
        }
        return true;
    }

根据KEY的名称可知对应的条目功能,通知对应的是mNotificationPreference,触发后会跳转到

AppNotificationSettings.java中
(3):AppNotificationSettings中获取通知权限项

该类主要是获取可进行的设置项(比如:全部阻止,显示时不发出提示音,覆盖“勿扰”设置)的当前状态,以及提供选项按钮进行设置。

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.app_notification_settings);
        mImportance = (ImportanceSeekBarPreference) findPreference(KEY_IMPORTANCE);
        mPriority =
                (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BYPASS_DND);
        mVisibilityOverride =
                (RestrictedDropDownPreference) getPreferenceScreen().findPreference(
                        KEY_VISIBILITY_OVERRIDE);
        mBlock = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BLOCK);
        mSilent = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_SILENT);
        if (mPkgInfo != null) {
            mAppRow = mBackend.loadAppRow(mContext, mPm, mPkgInfo);

            NotificationManager.Policy policy =
                    NotificationManager.from(mContext).getNotificationPolicy();
            mDndVisualEffectsSuppressed = policy == null ? false : policy.suppressedVisualEffects != 0;

            // load settings intent
            ArrayMap<String, AppRow> rows = new ArrayMap<String, AppRow>();
            rows.put(mAppRow.pkg, mAppRow);
            collectConfigActivities(rows);

            setupImportancePrefs(mAppRow.systemApp, mAppRow.appImportance, mAppRow.banned);
            setupPriorityPref(mAppRow.appBypassDnd);
            setupVisOverridePref(mAppRow.appVisOverride);
            updateDependents(mAppRow.appImportance);
        }
    }

在onCreate()进行了初始化,主要代码如下:

mAppRow = mBackend.loadAppRow(mContext, mPm, mPkgInfo);//更加包名信息获取通知权限状态
...
//初始化相应控件的选择事件
setupImportancePrefs(mAppRow.systemApp, mAppRow.appImportance, mAppRow.banned);
//以下就是初始化相应的ui显示
setupPriorityPref(mAppRow.appBypassDnd);
setupVisOverridePref(mAppRow.appVisOverride);
updateDependents(mAppRow.appImportance);

setupImportancePrefs()函数是在NotificationSettingsBase.java类中的:

protected void setupImportancePrefs(boolean isSystemApp, int importance, boolean banned) {
        if (mShowSlider) {
            setVisible(mBlock, false);
            setVisible(mSilent, false);
            mImportance.setDisabledByAdmin(mSuspendedAppsAdmin);
            mImportance.setMinimumProgress(
                    isSystemApp ? Ranking.IMPORTANCE_MIN : Ranking.IMPORTANCE_NONE);
            mImportance.setMax(Ranking.IMPORTANCE_MAX);
            mImportance.setProgress(importance);
            mImportance.setAutoOn(importance == Ranking.IMPORTANCE_UNSPECIFIED);
            mImportance.setCallback(new ImportanceSeekBarPreference.Callback() {
                @Override
                public void onImportanceChanged(int progress, boolean fromUser) {
                    if (fromUser) {
                        mBackend.setImportance(mPkg, mUid, progress);
                    }
                    updateDependents(progress);
                }
            });
        } else {
            setVisible(mImportance, false);
            if (isSystemApp) {
                setVisible(mBlock, false);
                /// M: mSilent depends on mBlock, so remove mSilent when remove mBlock
                setVisible(mSilent, false);
            } else {
                boolean blocked = importance == Ranking.IMPORTANCE_NONE || banned;
                mBlock.setChecked(blocked);
                mBlock.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                    @Override
                    public boolean onPreferenceChange(Preference preference, Object newValue) {
                        final boolean blocked = (Boolean) newValue;
                        final int importance =
                                blocked ? Ranking.IMPORTANCE_NONE : Ranking.IMPORTANCE_UNSPECIFIED;
                        Log.d("kaypermission", "onPreferenceChange: blocked:" + blocked + " importance:" + importance);
                        mBackend.setImportance(mPkgInfo.packageName, mUid, importance);
                        updateDependents(importance);
                        return true;
                    }
                });

                mSilent.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                    @Override
                    public boolean onPreferenceChange(Preference preference, Object newValue) {
                        final boolean silenced = (Boolean) newValue;
                        final int importance =
                                silenced ? Ranking.IMPORTANCE_LOW : Ranking.IMPORTANCE_UNSPECIFIED;
                        mBackend.setImportance(mPkgInfo.packageName, mUid, importance);
                        updateDependents(importance);
                        return true;
                    }
                });
                updateDependents(banned ? Ranking.IMPORTANCE_NONE : importance);
            }
        }
    }

全部阻止对应的是mBlock.setOnPreferenceChangeListener(),点击触发后会先调用mBackend.setImportance()功能设置并走到AppNotificationSettings.java的updateDependents()更新ui显示

 @Override
    protected void updateDependents(int importance) {
        LockPatternUtils utils = new LockPatternUtils(getActivity());
        boolean lockscreenSecure = utils.isSecure(UserHandle.myUserId());
        UserInfo parentUser = mUm.getProfileParent(UserHandle.myUserId());
        if (parentUser != null){
            lockscreenSecure |= utils.isSecure(parentUser.id);
        }

        if (getPreferenceScreen().findPreference(mBlock.getKey()) != null) {
            setVisible(mSilent, checkCanBeVisible(Ranking.IMPORTANCE_MIN, importance));
            mSilent.setChecked(importance == Ranking.IMPORTANCE_LOW);
        }
        setVisible(mPriority, checkCanBeVisible(Ranking.IMPORTANCE_DEFAULT, importance)
                && !mDndVisualEffectsSuppressed);
        setVisible(mVisibilityOverride,
                checkCanBeVisible(Ranking.IMPORTANCE_MIN, importance) && lockscreenSecure);
    }
三:小结

做个测试,在SystemUI中阻止某个app的默认开启的通知权限,功能有实现。

一:首先拷贝NotificationBackend.java的类到指定位置

二:使用如下函数进行设置
 private void setNotificationPermission(String packageName){
        PackageManager pm = mContext.getPackageManager();
            if (packageName != null) {
                try {
                    PackageInfo info = pm.getPackageInfo(packageName, 0);
        
                    if(info != null){
                        NotificationBackend mBackend = new NotificationBackend();
                        NotificationBackend.AppRow mAppRow = mBackend.loadAppRow(mContext, pm, info);
                        int importance = mBackend.getImportance(packageName, mAppRow.uid);
                        if(importance != 0 ){
                            mBackend.setImportance(packageName, mAppRow.uid, 0);
                        }
                    }

                } catch (PackageManager.NameNotFoundException e) {
                    
                }
            }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值