赞
踩
在Android系统中,状态栏(StatusBar)、导航栏(NavigationBar)和下拉菜单(ExPlan)是三个常见的用户界面元素,它们分别提供了一些基本的信息显示和交互功能。例如,状态栏可以显示时间、电量、信号等信息,导航栏可以提供返回、主页、多任务等按钮,下拉菜单可以提供快速设置、通知等选项。并不是所有客户的Android设备都需要或支持这些,有时候客户可能想要自由地控制它们的显示和隐藏。
本文将介绍如何在Android系统中定制添加状态栏、导航栏和下拉菜单的控制功能,以便客户可以根据需求使用。
要实现状态栏、导航栏和下拉菜单的控制功能,需要修改以下几个部分:
需要完成以下几个步骤:
在SystemUI模块的AndroidManifest.xml文件中 需要添加以下几行代码,用于声明要接收的广播:
<protected-broadcast android:name="sys.explan.show" />
<protected-broadcast android:name="sys.explan.hide" />
<protected-broadcast android:name="sys.statusbar.show" />
<protected-broadcast android:name="sys.statusbar.hide" />
<protected-broadcast android:name="sys.navigationbar.show" />
<protected-broadcast android:name="sys.navigationbar.hide" />
在SystemUI模块的NavigationBarController.java文件中需要添加一个函数,用于移除所有的导航栏:
public void removeNavigationBars() {
Display[] displays = mDisplayManager.getDisplays();
for (Display display : displays) {
removeNavigationBar(display.getDisplayId());
}
}
在SystemUI模块的PhoneStatusBarView.java文件中需要修改,用于根据系统属性来决定是否响应下拉菜单的触摸事件:
(这个文件如果用于动态控制 有bug,除了这个文件其他都正常修改 )
- return barConsumedEvent || super.onTouchEvent(event);
+ /* String value = SystemProperties.get("persist.sys.explan.enable", "false");
+ if(value.equals("true")){
+ return barConsumedEvent || super.onTouchEvent(event);
+ }else{
+ return true;
+ }*/
+ //
+ return barConsumedEvent || super.onTouchEvent(event);
在SystemUI模块的StatusBar.java文件中,我们需要添加以下几行代码,用于声明和初始化一些变量和方法:
+ private static final String ACTION_HIDE_EXPLAN = "sys.explan.hide";
+ private static final String ACTION_SHOW_EXPLAN = "sys.explan.show";
+ private static final String ACTION_HIDE_STATUS_BAR = "sys.statusbar.hide";
+ private static final String ACTION_SHOW_STATUS_BAR = "sys.statusbar.show";
+ private static final String ACTION_HIDE_NAVIGATION_BAR = "sys.navigationbar.hide";
+ private static final String ACTION_SHOW_NAVIGATION_BAR = "sys.navigationbar.show";
+ private static final String SYS_PROPERTY_STATUS_BAR = "persist.sys.statusbar.enable";
+ private static final String SYS_PROPERTY_NAVIGATION_BAR = "persist.sys.navigationbar.enable";
+ private static final String SYS_PROPERTY_EXPLAN = "persist.sys.explan.enable";
+ protected StatusBarManager mStatusBarManager;
+
public StatusBar(Context context) {
super(context);
...
+ mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
...
}
+
+ public void explan_show() {
+ mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
+ }
+ public void explan_hide() {
+ mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
+ }
在SystemUI模块的StatusBar.java文件中,还需要修改以下几行代码,用于根据系统属性来决定初始化是否创建或隐藏状态栏、导航栏和下拉菜单:
- createAndAddWindows(result);
-
+ //ln28_add_start
+ if (!SystemProperties.getBoolean(SYS_PROPERTY_STATUS_BAR, false)) {
+ mStatusBarWindowController.setBarVisibility(View.GONE);
+ }
+ //ln28_add_end
if (mWallpaperSupported) {
...
}
-
- createNavigationBar(result);
-
+ //ln28_add_start
+ if (SystemProperties.getBoolean(SYS_PROPERTY_NAVIGATION_BAR, false)) {
+ createNavigationBar(result);
+ }
+ if (SystemProperties.getBoolean(SYS_PROPERTY_EXPLAN, false)) {
+ explan_show();
+ }
+ //ln28_add_end
if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) {
...
}
在SystemUI模块的StatusBar.java文件中,还还需要添加以下几行代码,用于注册和处理我们要接收的广播 实现逻辑动态控制:
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_BAR);
+ filter.addAction(ACTION_SHOW_NAVIGATION_BAR);
+ filter.addAction(ACTION_HIDE_STATUS_BAR);
+ filter.addAction(ACTION_SHOW_STATUS_BAR);
+ filter.addAction(ACTION_HIDE_EXPLAN);
+ filter.addAction(ACTION_SHOW_EXPLAN);
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
...
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
...
} else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
mQSPanel.showDeviceMonitoringDialog();
+ } else if (ACTION_HIDE_NAVIGATION_BAR.equals(action)) {
+ mNavigationBarController.removeNavigationBars();
+ SystemProperties.set(SYS_PROPERTY_NAVIGATION_BAR, "false");
+ } else if (ACTION_SHOW_NAVIGATION_BAR.equals(action)) {
+ createNavigationBar(null);
+ SystemProperties.set(SYS_PROPERTY_NAVIGATION_BAR, "true");
+ } else if (ACTION_HIDE_STATUS_BAR.equals(action)) {
+ mStatusBarWindowController.setBarVisibility(View.GONE);
+ SystemProperties.set(SYS_PROPERTY_STATUS_BAR, "false");
+ } else if (ACTION_SHOW_STATUS_BAR.equals(action)) {
+ mStatusBarWindowController.setBarVisibility(View.VISIBLE);
+ SystemProperties.set(SYS_PROPERTY_STATUS_BAR, "true");
+ } else if (ACTION_HIDE_EXPLAN.equals(action)) {
+ explan_hide();
+ SystemProperties.set(SYS_PROPERTY_EXPLAN, "false");
+ } else if (ACTION_SHOW_EXPLAN.equals(action)) {
+ explan_show();
+ SystemProperties.set(SYS_PROPERTY_EXPLAN, "true");
}
}
};
OK 到这我们就完成了SystemUI模块的修改,是不是很简单? 接下来我们需要修改Settings模块。
在Settings模块的strings.xml文件中,需要添加以下几行代码,用于定义我们要显示的开关偏好项的标题:
<string name="ctrl_statusbar">状态栏</string>
<string name="ctrl_explan">下拉菜单</string>
<string name="ctrl_navigationbar">导航栏</string>
在Settings模块的display_settings.xml文件中,需要添加以下几行代码,用于创建我们要显示的开关偏好项,并指定它们的键值和标题:
<SwitchPreference
android:key="ctrl_statusbar"
android:title="@string/ctrl_statusbar"/>
<SwitchPreference
android:key="ctrl_navigationbar"
android:title="@string/ctrl_navigationbar"/>
<SwitchPreference
android:key="ctrl_explan"
android:title="@string/ctrl_explan"/>
在Settings模块的DisplaySettings.java文件中,需要添加以下几行代码,用于注册我们要控制的开关偏好项的控制器:
controllers.add(new ThemePreferenceController(context));
controllers.add(new BrightnessLevelPreferenceController(context, lifecycle));
controllers.add(new HdmiSettingsPreferenceController(context, KET_HDMI_SETTINGS));
+ controllers.add(new StatusBarPreferenceController(context));
+ controllers.add(new NavigationBarPreferenceController(context));
+ controllers.add(new ExPlanPreferenceController(context));
在Settings模块的StatusBarPreferenceController.java文件中,需要添加以下几行代码,用于实现状态栏开关偏好项的控制器,主要负责读取和写入系统属性,以及发送控制广播:
package com.android.settings.display;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
import android.content.Intent;
import android.util.Log;
import android.os.SystemProperties;
public class StatusBarPreferenceController extends AbstractPreferenceController implements
Preference.OnPreferenceChangeListener {
private static final String TAG = "StatusBarCtrl";
private static final boolean DEBUG = true;
private static final String KEY_STATUS_BAR = "ctrl_statusbar";
private static final String SYS_PROP_STATUS_BAR_ENABLE = "persist.sys.statusbar.enable";
public static final String ACTION_HIDE_STATUS_BAR = "sys.statusbar.hide";
public static final String ACTION_SHOW_STATUS_BAR = "sys.statusbar.show";
public StatusBarPreferenceController(Context context) {
super(context);
}
@Override
public String getPreferenceKey() {
return KEY_STATUS_BAR;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void displayPreference(PreferenceScreen screen) {
if (!isAvailable()) {
setVisible(screen, KEY_STATUS_BAR, false);
return;
}
final SwitchPreference mStatusBarPreference = screen.findPreference(KEY_STATUS_BAR);
if (mStatusBarPreference != null) {
String value = SystemProperties.get(SYS_PROP_STATUS_BAR_ENABLE, "false");
mStatusBarPreference.setChecked(value.equals("true"));
mStatusBarPreference.setOnPreferenceChangeListener(this);
}
}
@Override
public void updateState(Preference preference) {
String value = SystemProperties.get(SYS_PROP_STATUS_BAR_ENABLE, "false");
((SwitchPreference) preference).setChecked(value.equals("true"));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (DEBUG) {
Log.d(TAG, "key value " + value);
}
Intent intent = new Intent();
if (value) {
intent.setAction(ACTION_SHOW_STATUS_BAR);
} else {
intent.setAction(ACTION_HIDE_STATUS_BAR);
}
mContext.sendBroadcast(intent);
return true;
}
}
在Settings模块的NavigationBarPreferenceController.java文件中,需要添加以下几行代码,用于实现导航栏开关偏好项的控制器,主要负责读取和写入系统属性,以及发送控制广播:
package com.android.settings.display;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
import android.content.Intent;
import android.util.Log;
import android.os.SystemProperties;
public class NavigationBarPreferenceController extends AbstractPreferenceController
implements Preference.OnPreferenceChangeListener {
private static final String TAG = "NavigationBarCtrl";
private static final boolean DEBUG = true;
private static final String KEY_NAVIGATION_BAR = "ctrl_navigationbar";
private static final String SYS_PROP_NAVIGATION_BAR_ENABLE = "persist.sys.navigationbar.enable";
public static final String ACTION_HIDE_NAVIGATION_BAR = "sys.navigationbar.hide";
public static final String ACTION_SHOW_NAVIGATION_BAR = "sys.navigationbar.show";
public NavigationBarPreferenceController(Context context) {
super(context);
}
@Override
public String getPreferenceKey() {
return KEY_NAVIGATION_BAR;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void displayPreference(PreferenceScreen screen) {
if (!isAvailable()) {
setVisible(screen, KEY_NAVIGATION_BAR, false);
return;
}
final SwitchPreference mNavigationBarPreference = screen.findPreference(KEY_NAVIGATION_BAR);
if (mNavigationBarPreference != null) {
String value = SystemProperties.get(SYS_PROP_NAVIGATION_BAR_ENABLE, "false");
mNavigationBarPreference.setChecked(value.equals("true"));
mNavigationBarPreference.setOnPreferenceChangeListener(this);
}
}
@Override
public void updateState(Preference preference) {
String value = SystemProperties.get(SYS_PROP_NAVIGATION_BAR_ENABLE, "false");
((SwitchPreference) preference).setChecked(value.equals("true"));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (DEBUG) {
Log.d(TAG, "key value " + value);
}
Intent intent = new Intent();
if (value) {
intent.setAction(ACTION_SHOW_NAVIGATION_BAR);
} else {
intent.setAction(ACTION_HIDE_NAVIGATION_BAR);
}
mContext.sendBroadcast(intent);
return true;
}
}
在Settings模块的ExPlanPreferenceController.java文件中,需要添加以下几行代码,用于实现下拉菜单开关偏好项的控制器,主要负责读取和写入系统属性,以及发送控制广播:
package com.android.settings.display;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
import android.content.Intent;
import android.util.Log;
import android.os.SystemProperties;
public class ExPlanPreferenceController extends AbstractPreferenceController implements
Preference.OnPreferenceChangeListener {
private static final String TAG = "ExPlanCtrl";
private static final boolean DEBUG = true;
private static final String KEY_EXPLAN = "ctrl_explan";
private static final String SYS_PROP_EXPLAN_ENABLE = "persist.sys.explan.enable";
private static final String ACTION_HIDE_EXPLAN = "sys.explan.hide";
private static final String ACTION_SHOW_EXPLAN = "sys.explan.show";
public ExPlanPreferenceController(Context context) {
super(context);
}
@Override
public String getPreferenceKey() {
return KEY_EXPLAN;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void displayPreference(PreferenceScreen screen) {
if (!isAvailable()) {
setVisible(screen, KEY_EXPLAN, false);
return;
}
final SwitchPreference mExPlanPreference = screen.findPreference(KEY_EXPLAN);
if (mExPlanPreference != null) {
String value = SystemProperties.get(SYS_PROP_EXPLAN_ENABLE, "false");
mExPlanPreference.setChecked(value.equals("true"));
mExPlanPreference.setOnPreferenceChangeListener(this);
}
}
@Override
public void updateState(Preference preference) {
String value = SystemProperties.get(SYS_PROP_EXPLAN_ENABLE, "false");
((SwitchPreference) preference).setChecked(value.equals("true"));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (DEBUG) {
Log.d(TAG, "key value " + value);
}
Intent intent = new Intent();
if (value) {
intent.setAction(ACTION_SHOW_EXPLAN);
} else {
intent.setAction(ACTION_HIDE_EXPLAN);
}
mContext.sendBroadcast(intent);
return true;
}
}
这样就完成了Settings模块的修改,接下来直接编译并运行修改后的系统,并在设置中测试控制功能。
以下是我在模拟器上测试的结果,您可以看到状态栏、导航栏和下拉菜单的显示和隐藏效果:
这是全部关闭的效果
这是全部打开的效果
重启后看到设置保存 到此, 需求实现完毕。
忘记了 如果要设置属性默认值你们自己随便找个位置添加就OK了。
+PRODUCT_PROPERTY_OVERRIDES += persist.sys.statusbar.enable=true
+PRODUCT_PROPERTY_OVERRIDES += persist.sys.navigationbar.enable=true
+PRODUCT_PROPERTY_OVERRIDES += persist.sys.explan.enable=true
本文介绍了如何在Android系统中添加状态栏、导航栏和下拉菜单的控制功能,主要涉及了SystemUI模块和Settings模块的修改,以及系统属性和广播的使用。这些功能可以让用户控制和调用决定是否启用显示xx。
希望本文对你有所帮助,如果有任何问题或建议,请私信和留言。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。