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
發佈了19 篇原創文章 · 獲贊 14 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章