Android9.0勿扰模式【Do Not Disturb】

前言

最近使用客户的launcher设置音量时,会弹出一个界面,用于授权,用于给【勿扰模式】进行授权。

授权界面的源码

通过adb shell 指令获取当前的包名和界面,发现显示如下:

com.android.Settings.Settings$ZenAccessSettingsActivity

明显界面已经跳转到了原生setting app,一番搜索,该界面的实现源码如下:

packages/apps/Settings/src/com/android/settings/notification/ZenAccessSettings.java 

在这里,主要通过如下方法获取所有需要勿扰权限的app:

private void reloadList() {
    final PreferenceScreen screen = getPreferenceScreen();
    screen.removeAll();
    final ArrayList<ApplicationInfo> apps = new ArrayList<>();
    final ArraySet<String> requesting = getPackagesRequestingNotificationPolicyAccess();
    if (!requesting.isEmpty()) {
        final List<ApplicationInfo> installed = mPkgMan.getInstalledApplications(0);
        if (installed != null) {
            for (ApplicationInfo app : installed) {
                if (requesting.contains(app.packageName)) {
                    apps.add(app);
                }
            }
        }
    }
    ArraySet<String> autoApproved = new ArraySet<>();
    autoApproved.addAll(mNoMan.getEnabledNotificationListenerPackages());
    requesting.addAll(autoApproved);
    Collections.sort(apps, new PackageItemInfo.DisplayNameComparator(mPkgMan));
    for (ApplicationInfo app : apps) {
        final String pkg = app.packageName;
        final CharSequence label = app.loadLabel(mPkgMan);
        final SwitchPreference pref = new AppSwitchPreference(getPrefContext());
        pref.setKey(pkg);
        pref.setPersistent(false);
        pref.setIcon(app.loadIcon(mPkgMan));
        pref.setTitle(label);
        pref.setChecked(hasAccess(pkg));
        if (autoApproved.contains(pkg)) {
            pref.setEnabled(false);
            pref.setSummary(getString(R.string.zen_access_disabled_package_warning));
        }
        pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                final boolean access = (Boolean) newValue;
                if (access) {
                    new ScaryWarningDialogFragment()
                            .setPkgInfo(pkg, label)
                            .show(getFragmentManager(), "dialog");
                } else {
                    new FriendlyWarningDialogFragment()
                            .setPkgInfo(pkg, label)
                            .show(getFragmentManager(), "dialog");
                }
                return false;
            }
        });
        screen.addPreference(pref);
    }
}

这里可以获取到所有需要授权的app,接着需要用户去点击开关进行授权,这里授权的主要方法如下:

private static void setAccess(final Context context, final String pkg, final boolean access) {
    logSpecialPermissionChange(access, pkg, context);
    AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            final NotificationManager mgr = context.getSystemService(NotificationManager.class);
            mgr.setNotificationPolicyAccessGranted(pkg, access);
        }
    });
}

该方法的关键实现是如下函数:

mgr.setNotificationPolicyAccessGranted(pkg, access);

通过搜索发现,mgr定义如下“

final NotificationManager mgr = context.getSystemService(NotificationManager.class);

这么看来,想要不弹出授权界面,在系统起来的时候,给该应用进行授权即可。这次选择在自己开发的系统服务中进行授权;

final NotificationManager mgr = context.getSystemService(NotificationManager.class);
mgr.setNotificationPolicyAccessGranted(pkg, access);

到此可解决该问题。

需要注意的是,应用需要先在AndroidManifest.xml中申请如下权限:

android.permission.ACCESS_NOTIFICATION_POLICY
发布了18 篇原创文章 · 获赞 13 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/u010456460/article/details/104344464