美文网首页
Android5.1 设备进入沉浸式模式

Android5.1 设备进入沉浸式模式

作者: 100个大西瓜 | 来源:发表于2020-06-17 10:10 被阅读0次

    参考

    复制对应代码进adb界面中确认

    全部软件沉浸虚拟键:  adb shell settings put global policy_control immersive.navigation=*

    沉浸状态栏+虚拟键: adb shell settings put global policy_control immersive.full=*

    沉浸虚拟键,但不沉浸桌面.设置.android.相机:adb shell settings put global policy_control immersive.navigation=apps,-com.google.android.apps.nexuslauncher,-com.android.settings,-android,-com.google.android.GoogleCamera(这个没有全部软件沉浸的亮屏延迟bug)

    恢复官方默认:  adb shell settings put global policy_control null

    以上来自链接。


    逐一试了之后,发现 只有 “adb shell settings put global policy_control immersive.navigation=*” 符合要求。

    在源码中搜索 “policy_control”,发现

    frameworks/base/core/java/android/provider/Settings.java:7036: 

         public static final String POLICY_CONTROL = "policy_control";

        全名为 android.provider.Settings.Global.POLICY_CONTROL;

    搜索了 "POLICY_CONTROL ",匹配到的有:

    frameworks/base/core/java/android/provider/Settings.java:7036

        public static final String POLICY_CONTROL = "policy_control";

    frameworks/base/policy/src/com/android/internal/policy/impl/PolicyControl.java:40

    这里说明了配置沉浸式模式的格式,代码中也有这个说明对应上的。

    参考:Android7.0隐藏Immersive Mode提示

     /**

    * Runtime adjustments applied to the global window policy.

    *

    * This includes forcing immersive mode behavior for one or both system bars (based on a package

    * list) and permanently disabling immersive mode confirmations for specific packages.

    *

    * Control by setting {@link Settings.Global.POLICY_CONTROL} to one or more name-value pairs.

    * e.g.

    *  to force immersive mode everywhere:

    *    "immersive.full=*"

    *  to force transient status for all apps except a specific package:

    *    "immersive.status=apps,-com.package"

    *  to disable the immersive mode confirmations for specific packages:

    *    "immersive.preconfirms=com.package.one,com.package.two"

    *

    * Separate multiple name-value pairs with ':'

    *  e.g. "immersive.status=apps:immersive.preconfirms=*"

    */

    frameworks/base/policy/src/com/android/internal/policy/impl/PolicyControl.java:119:                     

    public static void reloadFromSetting(Context context) {

        if (DEBUG) Slog.d(TAG,"reloadFromSetting()");

        String value =null;

        try {

            value = Settings.Global.getStringForUser(context.getContentResolver(),

                Settings.Global.POLICY_CONTROL,

                UserHandle.USER_CURRENT);

            Log.d(TAG,"reloadFromSetting: " + value);

            if (sSettingValue !=null &&sSettingValue.equals(value)) {

                return;

            }

            setFilters(value);

            sSettingValue = value;

        } catch (Throwable t) {

            Slog.w(TAG,"Error loading policy control, value=" + value, t);

        }

    }

    frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java:783: 

    class SettingsObserverextends ContentObserver{

        SettingsObserver(Handler handler) {

            super(handler);

        }

        void observe() {

            // Observe all users' changes

            ContentResolver resolver =mContext.getContentResolver();

            //省略其他无关的

            ........

            resolver.registerContentObserver(Settings.Global.getUriFor(

                    Settings.Global.POLICY_CONTROL),false,this,

                    UserHandle.USER_ALL);

            // 省略其他无关的

            .......

        updateSettings();

    }

    //好多无关的代码就不贴了

    贴了那么多,也没说到怎么改;参照注释说明:

    <!-- Initial value for the Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS setting,

    which is a comma separated list of packages that no longer need confirmation

    for immersive mode.

    Override to disable immersive mode confirmation for certain packages. -->

    <string name="def_immersive_mode_confirmations" translatable="false"></string>

    以为就是改这里,将配置修改为

    <string name="def_immersive_mode_confirmations" translatable="false">immersive.navigation=*</string>

    编译之后发现并没有效果,又重新看了上面的ADB 命令:

    adb shell settings put global policy_control immersive.navigation=*

    发现def_immersive_mode_confirmations 对应的值只是在设备初始化中被应用:

    com.android.providers.settings.DatabaseHelper

    {

        loadStringSetting(stmt, Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,

          R.string.def_immersive_mode_confirmations);
    }

    而Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS = "immersive_mode_confirmations";

    而我们要改的是 policy_control ,且有全局作用的,故应该在

    com.android.providers.settings.DatabaseHelper#loadGlobalSettings(SQLiteDatabase db)中实现

    private void loadGlobalSettings(SQLiteDatabase db) {

        SQLiteStatement stmt =null;

    try {

            stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"

                    +" VALUES(?,?);");

            ……

        // --- New global settings start here

            if (mAdd) { 

              //2020/6/16 默认开启沉浸式,自动隐藏导航栏       

                 loadStringSetting(stmt, Settings.Global.POLICY_CONTROL, R.string.def_policy_control);    

            }

            } finally {

                if (stmt !=null) stmt.close();

            }

    }

    其中 def_policy_control 为新定义的String,如下

    <string name="def_policy_control" translatable="false">immersive.navigation=*</string>

    编译后开机 生效了。

    对java代码的格式化很不好,还需要自己手动调整

    相关文章

      网友评论

          本文标题:Android5.1 设备进入沉浸式模式

          本文链接:https://www.haomeiwen.com/subject/vdsjxktx.html