文章目录
- 前言
- 一、创建全局变量
- 二、设置应用添加隐藏导航栏按钮
- 三、添加按钮功能
- 四、动态隐藏还有显示功能
- 五、创建系统导航栏广播接口
- 总结
前言
关于Android系统的状态栏,不同的客户有不同的需求: 有些客户需要永久隐藏状态栏,有些客户需要在设置显示中添加按钮可自行选择是否显示和隐藏,有些客户需要给出调用接口供APP去调用设置等;
一、创建全局变量
1、创建全局变量并保存状态栏状态,是为了系统级应用和整个框架层都能获取到该变量值,该变量值在掉电或者重启都不会丢失(除了恢复出厂设置Q 或者重刷系统固件之外) ;
2、创建全局变量
配置路径: frameworks/base/core/java/android/provider/Settings.java
定义了一个SYSTEM_HIDE_STATUS_BAR 全局变量: SYSTEM_HIDE_STATUS_BAR = “hide_status_bar”
这个是需要放在 public static final class System extends NameValueTable {
里面的哦
/**
* add by LQX at 20240116
*/
public static final String SYSTEM_HIDE_STATUS_BAR = "hide_status_bar";
3、定义全局变量的默认值
配置路径: frameworks/base/packages/SettingsProvider/res/values/defaults.xml
设置引用的名称格式为: def_ + SYSTEM_HIDE_STATUS_BAR 的字符值 = def_hide_status_bar,值为bool类型;
值为true: 隐藏状态栏;
值为false: 显示状态栏;
<!-- add by LQX -->
<bool name="def_hide_status_bar">false</bool>
<!-- end, add by LQX -->
二、设置应用添加隐藏导航栏按钮
1、在 设置->显示 里添加导航栏按钮;
2、按钮标题为“隐藏导航栏”
这里以英文和中文字体为例,其他字体需要的话也同理添加;
英文字体(系统为英文语言时显示) : packages/apps/Settings/res/values/strings.xml
<!-- add by LQX-->
<string name="hide_status_bar">Hide Status Bar</string>
<!-- end, add by LQX-->
中文字体: packages/apps/Settings/res/values-zh-rCN/strings.xml
<!-- add by LQX-->
<string name="hide_status_bar">隐藏状态栏</string>
<!-- end, add by LQX-->
3、添加按钮布局
(1) 选择在 设置->显示 里面添加
对应的布局文件: packages/apps/Settings/res/xml/display_settings.xml
对应的按钮类型,这里选择为: SwitchPreference
(2)在对应的位置添加按钮控件
这里选择是在“屏幕超时”后面添加:
android:key=“hide_status_bar” ===>按钮控制健值
android:title=“@string/hide_status_bar”= = >标题,使用上面2中配置好的
<!-- add by LQX-->
<SwitchPreference
android:key="hide_status_bar"
android:title="@string/hide_status_bar" />
<!-- end,add by LQX-->
4、这样按钮就能在 设置->显示 中,显示出来了
但此时点击按钮是没有作用的,对应的按钮功能还没有添加进去:
三、添加按钮功能
1、添加功能代码
创建一个java文件:
目录路径: packages/apps/Settings/src/com/android/settings/display/
创建一个java文件: HideStatusBarPreferenceController
功能代码如下:
package com.android.settings.display;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.preference.Preference;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
import android.content.Intent;
import android.util.Log;
public class HideStatusBarPreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
private static final String TAG = "HideStatusBar";
private static final boolean DEBUG = true;
private static final String KEY_HIDE_STATUS_BAR = "hide_status_bar";
public static final String ACTION_HIDE_STATUS_BAR = "action.ACTION_HIDE_STATUS_BAR";
public HideStatusBarPreferenceController(Context context) {
super(context);
}
@Override
public String getPreferenceKey() {
return KEY_HIDE_STATUS_BAR;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void updateState(Preference preference) {
int value = Settings.System.getInt(
mContext.getContentResolver(), Settings.System.SYSTEM_HIDE_STATUS_BAR, 0);
((SwitchPreference) preference).setChecked(value != 0);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if(DEBUG) {
Log.d(TAG, "key value " + value);
}
Settings.System.putInt(
mContext.getContentResolver(), Settings.System.SYSTEM_HIDE_STATUS_BAR, value ? 1 : 0);
Intent intent = new Intent(ACTION_HIDE_STATUS_BAR);
mContext.sendBroadcast(intent); //发送广播
return true;
}
}
四、动态隐藏还有显示功能
1、相关修改代码文件:
frameworks/base/packages/SystemUI\src\com/android/systemui/statusbar/phone/StatusBar.java
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
2、主要修改代码
路径:frameworks/base/packages/SystemUl/src/com/android/systemui/lstatusbar/phone/StatusBar.java
--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -259,6 +259,8 @@ public class StatusBar extends SystemUI implements DemoMode,
public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
+ public static final String ACTION_HIDE_STATUS_BAR = "action.ACTION_HIDE_STATUS_BAR"; //add by LQX
+
private static final String BANNER_ACTION_CANCEL =
"com.android.systemui.statusbar.banner_action_cancel";
private static final String BANNER_ACTION_SETUP =
@@ -1099,7 +1101,20 @@ public class StatusBar extends SystemUI implements DemoMode,
mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
mNotificationLogger.setHeadsUpManager(mHeadsUpManager);
//createNavigationBar(result);
+ setStatusBar(); //add by LQX开机设置状态栏栏状态
+
if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) {
mLockscreenWallpaper = mLockscreenWallpaperLazy.get();
@@ -1288,6 +1303,7 @@ public class StatusBar extends SystemUI implements DemoMode,
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
+ filter.addAction(ACTION_HIDE_STATUS_BAR); //add by LQX接收设置应用发送出来的广播
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
}
@@ -1362,6 +1378,45 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
+//add by LQX
+private void setStatusBar() {
+ boolean hideStatusBar = Settings.System.getInt(mContext.getContentResolver(),Settings.System.SYSTEM_HIDE_STATUS_BAR,0) != 0;
+
+ if(hideStatusBar)
+ hideStatusBar();
+ else{
+ showStatusBar();
+ }
+ }
+
+ private void showStatusBar() {
+ if (mPhoneStatusBarWindow!=null){
+ Log.d(TAG,"====== show StatusBar ======");
+ mPhoneStatusBarWindow.setVisibility(View.VISIBLE);
+ }
+ }
+
+ private void hideStatusBar() {
+ if (mPhoneStatusBarWindow != null){
+ Log.d(TAG,"====== hide StatusBar ======");
+ mPhoneStatusBarWindow.setVisibility(View.GONE);
+ }
+ }
+//end,add by LQX
+
// TODO(b/117478341): This was left such that CarStatusBar can override this method.
// Try to remove this.
@@ -2804,6 +2862,10 @@ public class StatusBar extends SystemUI implements DemoMode,
}
else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
mQSPanel.showDeviceMonitoringDialog();
+ }
+ else if(ACTION_HIDE_STATUS_BAR.equals(action)) {
+ setStatusBar();
+ }
}
}
};
4、现在系统默认是隐藏导航栏,如需默认隐藏状态栏,请按下面的设置即可
文件:frameworks/base/packages/SettingsProvider/res/values/defaults.xm
值为true: 隐藏状态栏:
值为false: 显示状态栏
<bool name="def_hide_status_bar">true</bool>
五、创建系统导航栏广播接口
1、定义导航栏显示与隐藏的广播
public static final String ACTION_API_HIDE_STATUS_BAR = "action.ACTION_API_HIDE_STATUS_BAR"; //add by LQX 隐藏状态栏广播
public static final String ACTION_API_SHOW_STATUS_BAR = "action.ACTION_API_SHOW_STATUS_BAR"; //add by LQX 显示状态栏广播
2、系统代码实现
文件路径:frameworks/base/packages/SystemUl/src/com/android/systemui/statusbar/phone/StatusBar.java
创建了两个接收广播,待应用发送这两个广播来实现导航栏隐藏和显示;
--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -259,6 +259,10 @@ public class StatusBar extends SystemUI implements DemoMode,
public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
public static final String ACTION_HIDE_NAVIGATION = "action.ACTION_HIDE_NAVIGATION"; //add by LQX
+ public static final String ACTION_API_HIDE_STATUS_BAR = "action.ACTION_API_HIDE_STATUS_BAR"; //add by LQX 隐藏状态栏广播
+ public static final String ACTION_API_SHOW_STATUS_BAR = "action.ACTION_API_SHOW_STATUS_BAR"; //add by LQX 显示状态栏广播
+
private static final String BANNER_ACTION_CANCEL =
"com.android.systemui.statusbar.banner_action_cancel";
@@ -1288,6 +1305,9 @@ public class StatusBar extends SystemUI implements DemoMode,
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
filter.addAction(ACTION_HIDE_NAVIGATION); //add by LQX
+ filter.addAction(ACTION_API_HIDE_STATUS_BAR); //add by LQX 添加到广播队列里
+ filter.addAction(ACTION_API_SHOW_STATUS_BAR); //add by LQX 添加到广播队列里
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
}
// TODO(b/117478341): This was left such that CarStatusBar can override this method.
// Try to remove this.
protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
@@ -2804,7 +2878,19 @@ public class StatusBar extends SystemUI implements DemoMode,
}
else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
mQSPanel.showDeviceMonitoringDialog();
}
else if(ACTION_HIDE_STATUS_BAR.equals(action)) {
setStatusBar();
}
+ else if(ACTION_API_HIDE_STATUS_BAR.equals(action)) {
+ hideStatusBar(); //隐藏状态栏
+ }
+ else if(ACTION_API_SHOW_STATUS_BAR.equals(action)) {
+ showStatusBar(); //显示状态栏
+ }
}
总结
教程结束!编译成功后可以先用adb测试:
PS:对了!踩到的坑,改了系统api需要更新
make update-api
adb shell
am broadcast -a "action.ACTION_API_SHOW_STATUS_BAR"
am broadcast -a "action.ACTION_API_HIDE_STATUS_BAR"