Android11.0 hides status bar and navigation bar

Hide status bar and navigation bar

This article describes the Android11 ​​system settings - adding hidden status bar and navigation bar switches and function implementation in the display.

Add global state saving configuration

Before the M (Android5.0) version, the system settings in the SettingsProvider were stored in the settings.db database; but after L (Android6.0), the system settings in the SettingsProvider were changed to xml and stored in the data partition. , the path is /data/system/users/0/:
settings_global.xml
settings_secure.xml
settings_system.xml< /span>

  1. Add global variables in Settings and modify the path /frameworks/base/core/java/android/provider/Settings.java;
public static final class Global extends NameValueTable{
    
    
  //********省略代码******
  
        /**
         * Hide Navigation.
         *
         * @hide
         */
        public static final String HIDE_NAVIGATION = "hide_navigation";

        /**
         * Hide StatusBar.
         *
         * @hide
         */
        public static final String HIDE_STATUSBAR = "hide_statusbar";
        
  //********省略代码******
}
  1. Add switch default values ​​and modify the path /frameworks/base/packages/SettingsProvider/res/values/defaults.xml;
<resources>
//********省略代码******
    <integer name="def_hide_navigation">0</integer>
    <integer name="def_hide_statusbar">0</integer>
//********省略代码******
</resources>
  1. Add proto and modify the path /frameworks/base/core/proto/android/providers/settings/global.proto;
//********省略代码******

    message Display {
    
    
        //********省略代码******
        optional SettingProto hide_navigation_on = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
        optional SettingProto hide_statusbar_on = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
    }

//********省略代码******
  1. Switch default value loading, modify the path /frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java;
//********省略代码******

private void loadGlobalSettings(SQLiteDatabase db){
    
    

       loadIntegerSetting(stmt, Settings.Global.HIDE_NAVIGATION, R.integer.def_hide_navigation);
       loadIntegerSetting(stmt, Settings.Global.HIDE_STATUSBAR, R.integer.def_hide_statusbar);

}

//********省略代码******
  1. Modify the path /frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java;
//********省略代码******

        final long displayToken = p.start(GlobalSettingsProto.DISPLAY);
        //********省略代码******
        dumpSetting(s, p,
                Settings.Global.HIDE_NAVIGATION,
                GlobalSettingsProto.Display.HIDE_NAVIGATION_ON);
        dumpSetting(s, p,
                Settings.Global.HIDE_STATUSBAR,
                GlobalSettingsProto.Display.HIDE_STATUSBAR_ON);
        p.end(displayToken);

//********省略代码******

Device-Add hide status bar and hide navigation bar switches in display

  1. Define the switch name text and modify the path /packages/app/Settings/res/values/strings.xml
//********省略代码******

    <string name="hide_navigation">Hide Navigation</string>
    <string name="hide_statusbar">Hide StatusBar</string>

//********省略代码******

Modify the path /packages/app/Settings/res/values-zh-rCN/strings.xml

//********省略代码******

    <string name="hide_navigation">隐藏导航栏</string>
    <string name="hide_statusbar">隐藏状态栏</string>

//********省略代码******
  1. Add switches to the layout and modify the path /packages/app/Settings/res/xml/display_settings.xml
//********省略代码******

    <SwitchPreference
        android:key="hide_navigation"
        android:title="@string/hide_navigation"
        settings:controller="com.android.settings.display.HideNavigationPreferenceController" />

    <SwitchPreference
        android:key="hide_statusbar"
        android:title="@string/hide_statusbar"
        settings:controller="com.android.settings.display.HideStatusBarPreferenceController" />

//********省略代码******
  1. Add the switch's controller class path: /packages/app/Settings/src/com/android/settings/display/HideStatusBarPreferenceController.java
    /packages/app/Settings/src /com/android/settings/display/HideNavigationPreferenceController.java
package com.android.settings.display;

import android.content.Context;
import android.content.Intent;
import android.provider.Settings;

import com.android.settings.core.TogglePreferenceController;

import static android.content.Intent.ACTION_HIDE_STATUSBAR;

public class HideStatusBarPreferenceController extends TogglePreferenceController {
    
    
    private Context mContext;

    public HideStatusBarPreferenceController(Context context, String preferenceKey) {
    
    
        super(context, preferenceKey);
        mContext = context;
    }

    @Override
    public boolean isChecked() {
    
    
        return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.HIDE_STATUSBAR, 0) == 1 ? true : false;
    }

    @Override
    public boolean setChecked(boolean isChecked) {
    
    
        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.HIDE_STATUSBAR, isChecked ? 1 : 0);
        mContext.sendBroadcast(new Intent(ACTION_HIDE_STATUSBAR));
        return true;
    }

    @Override
    public int getAvailabilityStatus() {
    
    
        return AVAILABLE;
    }
}


package com.android.settings.display;

import android.content.Context;
import android.content.Intent;
import android.provider.Settings;

import com.android.settings.core.TogglePreferenceController;

import static android.content.Intent.ACTION_HIDE_NAVIGATION;

public class HideNavigationPreferenceController extends TogglePreferenceController {
    
    
    private Context mContext;

    public HideNavigationPreferenceController(Context context, String preferenceKey) {
    
    
        super(context, preferenceKey);
        mContext = context;
    }

    @Override
    public boolean isChecked() {
    
    
        return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.HIDE_NAVIGATION, 0) == 1 ? true : false;
    }

    @Override
    public boolean setChecked(boolean isChecked) {
    
    
        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.HIDE_NAVIGATION, isChecked ? 1 : 0);
        mContext.sendBroadcast(new Intent(ACTION_HIDE_NAVIGATION));
        return true;
    }

    @Override
    public int getAvailabilityStatus() {
    
    
        return AVAILABLE;
    }
}

Define the broadcast string for hiding the status bar and navigation bar

  1. Define the broadcast string and modify the path /frameworks/base/core/java/android/content/Intent.java
//********省略代码******

    /**
     * hide statusbar.
     *
     * @hide
     */
    public static final String ACTION_HIDE_STATUSBAR =
            "android.intent.action.HIDE_STATUSBAR";

    /**
     * hide navigation.
     *
     * @hide
     */
    public static final String ACTION_HIDE_NAVIGATION =
            "android.intent.action.HIDE_NAVIGATION";

//********省略代码******
  1. Add permissions and modify the path /frameworks/base/core/res/AndroidManifest.xml (if not added, the Sending non-protected broadcast xxxxxxx from system xxxxxxxxxx error will be reported when sending a broadcast, but it will not affect program execution)
//********省略代码******

    <protected-broadcast android:name="android.intent.action.HIDE_STATUSBAR" />
    <protected-broadcast android:name="android.intent.action.HIDE_NAVIGATION" />

//********省略代码******

Processing broadcasts in SystemUI to hide the status bar and navigation bar

  1. Modify the path/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
    Note: Many people on the Internet call createNavigationBar(result ) displays the navigation bar, and removeNavigationBar() hides the navigation bar. When the navigation bar is hidden in the Settings-Display interface and is displayed, the navigation bar button icon will not be in dark mode and will be unclear from the background, so use the method of hiding the navigation bar view. .
//********省略代码******

    private static final int MSG_HIDE_STATUSBAR = 10001;
    private static final int MSG_HIDE_NAVIGATION = 10002;

   protected class H extends Handler {
    
    
        @Override
        public void handleMessage(Message m) {
    
    
            switch (m.what) {
    
    
                //********省略代码******
                //新增
                case MSG_HIDE_STATUSBAR:
                    changeStatusBar();
                    break;
                case MSG_HIDE_NAVIGATION:
                    changeNavigationBar();
                    break;
            }
        }
    }

    @VisibleForTesting
    protected void registerBroadcastReceiver() {
    
    
        //********省略代码******
        filter.addAction(Intent.ACTION_HIDE_STATUSBAR);
        filter.addAction(Intent.ACTION_HIDE_NAVIGATION);
    }

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
    
            if (DEBUG) Log.v(TAG, "onReceive: " + intent);
            //********省略代码******
             else if (Intent.ACTION_HIDE_STATUSBAR.equals(action)) {
    
    
                mHandler.removeMessages(MSG_HIDE_STATUSBAR);
                mHandler.sendEmptyMessageDelayed(MSG_HIDE_STATUSBAR, 350);
            } else if (Intent.ACTION_HIDE_NAVIGATION.equals(action)) {
    
    
                mHandler.removeMessages(MSG_HIDE_NAVIGATION);
                mHandler.sendEmptyMessageDelayed(MSG_HIDE_NAVIGATION, 350);
            }
        }
    };


    protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
    
    
        //********省略代码******
        //更新状态栏及导航栏
        refreshStatusBarAndNavigation();
   }

    private void changeStatusBar() {
    
    
        boolean isShow = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.HIDE_STATUSBAR, 0) == 0;
        mPhoneStatusBarWindow.setVisibility(isShow ? VISIBLE : GONE);
    }

    private void changeNavigationBar() {
    
    
        boolean isShow = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.HIDE_NAVIGATION, 0) == 0;
        getNavigationBarView().getRootView().setVisibility(isShow ? VISIBLE : GONE);
    }

    private void refreshStatusBarAndNavigation() {
    
    
        changeStatusBar();

        boolean isShow = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.HIDE_NAVIGATION, 0) == 0;
        if (!isShow) {
    
    
            new Thread() {
    
    
                @Override
                public void run() {
    
    
                    while (true) {
    
    
                        if (null != getNavigationBarView()) {
    
    
                            mHandler.post(() -> changeNavigationBar());
                            return;
                        }
                        try {
    
    
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
    
    
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        }
    }

//********省略代码******

Guess you like

Origin blog.csdn.net/yjz_0314/article/details/132311438