0


Android系统 添加动态控制SystemUI状态栏、导航栏和下拉菜单

在Android系统中,状态栏(StatusBar)、导航栏(NavigationBar)和下拉菜单(ExPlan)是三个常见的用户界面元素,它们分别提供了一些基本的信息显示和交互功能。例如,状态栏可以显示时间、电量、信号等信息,导航栏可以提供返回、主页、多任务等按钮,下拉菜单可以提供快速设置、通知等选项。并不是所有客户的Android设备都需要或支持这些,有时候客户可能想要自由地控制它们的显示和隐藏。

本文将介绍如何在Android系统中定制添加状态栏、导航栏和下拉菜单的控制功能,以便客户可以根据需求使用。

实现步骤

要实现状态栏、导航栏和下拉菜单的控制功能,需要修改以下几个部分:

  • SystemUI模块:这是一个系统应用程序,负责显示和管理状态栏、导航栏和下拉菜单等界面元素。
  • Settings模块:这是一个系统应用程序,负责提供各种系统设置选项,包括显示设置。
  • 系统属性:这是一种用于存储和传递系统配置信息的机制,可以通过命令行或代码来读写。
  • 广播:这是一种用于在不同组件之间传递消息的机制,可以通过命令行或代码来发送和接收。

需要完成以下几个步骤:

  1. 在SystemUI模块中添加广播接收器,用于接收控制状态栏、导航栏和下拉菜单显示和隐藏的广播,并执行相应的操作。
  2. 在SystemUI模块中添加系统属性读取,用于获取状态栏、导航栏和下拉菜单的初始状态,并创建或移除相应的界面元素。
  3. 在Settings模块中添加开关偏好项,用于控制状态栏、导航栏和下拉菜单的开启和关闭,并发送相应的广播,并写入相应的系统属性。
  4. 编译并运行修改后的系统,并在设置中测试控制功能。

修改示例

SystemUI模块

frameworks/base/packages/SystemUI/AndroidManifest.xml

在SystemUI模块的AndroidManifest.xml文件中 需要添加以下几行代码,用于声明要接收的广播:

<protected-broadcastandroid:name="sys.explan.show"/><protected-broadcastandroid:name="sys.explan.hide"/><protected-broadcastandroid:name="sys.statusbar.show"/><protected-broadcastandroid:name="sys.statusbar.hide"/><protected-broadcastandroid:name="sys.navigationbar.show"/><protected-broadcastandroid:name="sys.navigationbar.hide"/>
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java

在SystemUI模块的NavigationBarController.java文件中需要添加一个函数,用于移除所有的导航栏:

publicvoidremoveNavigationBars(){Display[] displays = mDisplayManager.getDisplays();for(Display display : displays){removeNavigationBar(display.getDisplayId());}}
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java

在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);
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java

在SystemUI模块的StatusBar.java文件中,我们需要添加以下几行代码,用于声明和初始化一些变量和方法:

+privatestaticfinalStringACTION_HIDE_EXPLAN="sys.explan.hide";+privatestaticfinalStringACTION_SHOW_EXPLAN="sys.explan.show";+privatestaticfinalStringACTION_HIDE_STATUS_BAR="sys.statusbar.hide";+privatestaticfinalStringACTION_SHOW_STATUS_BAR="sys.statusbar.show";+privatestaticfinalStringACTION_HIDE_NAVIGATION_BAR="sys.navigationbar.hide";+privatestaticfinalStringACTION_SHOW_NAVIGATION_BAR="sys.navigationbar.show";+privatestaticfinalStringSYS_PROPERTY_STATUS_BAR="persist.sys.statusbar.enable";+privatestaticfinalStringSYS_PROPERTY_NAVIGATION_BAR="persist.sys.navigationbar.enable";+privatestaticfinalStringSYS_PROPERTY_EXPLAN="persist.sys.explan.enable";+protectedStatusBarManager mStatusBarManager;+publicStatusBar(Context context){super(context);...+         mStatusBarManager =(StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);...}++publicvoidexplan_show(){+        mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);+}+publicvoidexplan_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_endif(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_endif(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);}privatefinalBroadcastReceiver mBroadcastReceiver =newBroadcastReceiver(){@OverridepublicvoidonReceive(Context context,Intent intent){String action = intent.getAction();if(Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)){...}elseif(Intent.ACTION_SCREEN_OFF.equals(action)){...}elseif(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)){
                 mQSPanel.showDeviceMonitoringDialog();+}elseif(ACTION_HIDE_NAVIGATION_BAR.equals(action)){+                mNavigationBarController.removeNavigationBars();+SystemProperties.set(SYS_PROPERTY_NAVIGATION_BAR,"false");+}elseif(ACTION_SHOW_NAVIGATION_BAR.equals(action)){+createNavigationBar(null);+SystemProperties.set(SYS_PROPERTY_NAVIGATION_BAR,"true");+}elseif(ACTION_HIDE_STATUS_BAR.equals(action)){+                mStatusBarWindowController.setBarVisibility(View.GONE);+SystemProperties.set(SYS_PROPERTY_STATUS_BAR,"false");+}elseif(ACTION_SHOW_STATUS_BAR.equals(action)){+                mStatusBarWindowController.setBarVisibility(View.VISIBLE);+SystemProperties.set(SYS_PROPERTY_STATUS_BAR,"true");+}elseif(ACTION_HIDE_EXPLAN.equals(action)){+explan_hide();+SystemProperties.set(SYS_PROPERTY_EXPLAN,"false");+}elseif(ACTION_SHOW_EXPLAN.equals(action)){+explan_show();+SystemProperties.set(SYS_PROPERTY_EXPLAN,"true");}}};

OK 到这我们就完成了SystemUI模块的修改,是不是很简单? 接下来我们需要修改Settings模块。

Settings模块

packages/apps/Settings/res/values/strings.xml

在Settings模块的strings.xml文件中,需要添加以下几行代码,用于定义我们要显示的开关偏好项的标题:

<stringname="ctrl_statusbar">状态栏</string><stringname="ctrl_explan">下拉菜单</string><stringname="ctrl_navigationbar">导航栏</string>
packages/apps/Settings/res/xml/display_settings.xml

在Settings模块的display_settings.xml文件中,需要添加以下几行代码,用于创建我们要显示的开关偏好项,并指定它们的键值和标题:

<SwitchPreferenceandroid:key="ctrl_statusbar"android:title="@string/ctrl_statusbar"/><SwitchPreferenceandroid:key="ctrl_navigationbar"android:title="@string/ctrl_navigationbar"/><SwitchPreferenceandroid:key="ctrl_explan"android:title="@string/ctrl_explan"/>
packages/apps/Settings/src/com/android/settings/DisplaySettings.java

在Settings模块的DisplaySettings.java文件中,需要添加以下几行代码,用于注册我们要控制的开关偏好项的控制器:

        controllers.add(newThemePreferenceController(context));
        controllers.add(newBrightnessLevelPreferenceController(context, lifecycle));
        controllers.add(newHdmiSettingsPreferenceController(context,KET_HDMI_SETTINGS));+        controllers.add(newStatusBarPreferenceController(context));+        controllers.add(newNavigationBarPreferenceController(context));+        controllers.add(newExPlanPreferenceController(context));
packages/apps/Settings/src/com/android/settings/display/StatusBarPreferenceController.java

在Settings模块的StatusBarPreferenceController.java文件中,需要添加以下几行代码,用于实现状态栏开关偏好项的控制器,主要负责读取和写入系统属性,以及发送控制广播:

packagecom.android.settings.display;importandroid.content.Context;importandroid.provider.Settings;importandroidx.preference.SwitchPreference;importandroidx.preference.Preference;importandroidx.preference.PreferenceScreen;importcom.android.settings.core.PreferenceControllerMixin;importcom.android.settingslib.core.AbstractPreferenceController;importandroid.content.Intent;importandroid.util.Log;importandroid.os.SystemProperties;publicclassStatusBarPreferenceControllerextendsAbstractPreferenceControllerimplementsPreference.OnPreferenceChangeListener{privatestaticfinalStringTAG="StatusBarCtrl";privatestaticfinalbooleanDEBUG=true;privatestaticfinalStringKEY_STATUS_BAR="ctrl_statusbar";privatestaticfinalStringSYS_PROP_STATUS_BAR_ENABLE="persist.sys.statusbar.enable";publicstaticfinalStringACTION_HIDE_STATUS_BAR="sys.statusbar.hide";publicstaticfinalStringACTION_SHOW_STATUS_BAR="sys.statusbar.show";publicStatusBarPreferenceController(Context context){super(context);}@OverridepublicStringgetPreferenceKey(){returnKEY_STATUS_BAR;}@OverridepublicbooleanisAvailable(){returntrue;}@OverridepublicvoiddisplayPreference(PreferenceScreen screen){if(!isAvailable()){setVisible(screen,KEY_STATUS_BAR,false);return;}finalSwitchPreference 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);}}@OverridepublicvoidupdateState(Preference preference){String value =SystemProperties.get(SYS_PROP_STATUS_BAR_ENABLE,"false");((SwitchPreference) preference).setChecked(value.equals("true"));}@OverridepublicbooleanonPreferenceChange(Preference preference,Object newValue){boolean value =(Boolean) newValue;if(DEBUG){Log.d(TAG,"key value "+ value);}Intent intent =newIntent();if(value){
            intent.setAction(ACTION_SHOW_STATUS_BAR);}else{
            intent.setAction(ACTION_HIDE_STATUS_BAR);}
        mContext.sendBroadcast(intent);returntrue;}}
packages/apps/Settings/src/com/android/settings/display/NavigationBarPreferenceController.java

在Settings模块的NavigationBarPreferenceController.java文件中,需要添加以下几行代码,用于实现导航栏开关偏好项的控制器,主要负责读取和写入系统属性,以及发送控制广播:

packagecom.android.settings.display;importandroid.content.Context;importandroid.provider.Settings;importandroidx.preference.SwitchPreference;importandroidx.preference.Preference;importandroidx.preference.PreferenceScreen;importcom.android.settings.core.PreferenceControllerMixin;importcom.android.settingslib.core.AbstractPreferenceController;importandroid.content.Intent;importandroid.util.Log;importandroid.os.SystemProperties;publicclassNavigationBarPreferenceControllerextendsAbstractPreferenceControllerimplementsPreference.OnPreferenceChangeListener{privatestaticfinalStringTAG="NavigationBarCtrl";privatestaticfinalbooleanDEBUG=true;privatestaticfinalStringKEY_NAVIGATION_BAR="ctrl_navigationbar";privatestaticfinalStringSYS_PROP_NAVIGATION_BAR_ENABLE="persist.sys.navigationbar.enable";publicstaticfinalStringACTION_HIDE_NAVIGATION_BAR="sys.navigationbar.hide";publicstaticfinalStringACTION_SHOW_NAVIGATION_BAR="sys.navigationbar.show";publicNavigationBarPreferenceController(Context context){super(context);}@OverridepublicStringgetPreferenceKey(){returnKEY_NAVIGATION_BAR;}@OverridepublicbooleanisAvailable(){returntrue;}@OverridepublicvoiddisplayPreference(PreferenceScreen screen){if(!isAvailable()){setVisible(screen,KEY_NAVIGATION_BAR,false);return;}finalSwitchPreference 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);}}@OverridepublicvoidupdateState(Preference preference){String value =SystemProperties.get(SYS_PROP_NAVIGATION_BAR_ENABLE,"false");((SwitchPreference) preference).setChecked(value.equals("true"));}@OverridepublicbooleanonPreferenceChange(Preference preference,Object newValue){boolean value =(Boolean) newValue;if(DEBUG){Log.d(TAG,"key value "+ value);}Intent intent =newIntent();if(value){
            intent.setAction(ACTION_SHOW_NAVIGATION_BAR);}else{
            intent.setAction(ACTION_HIDE_NAVIGATION_BAR);}
        mContext.sendBroadcast(intent);returntrue;}}
packages/apps/Settings/src/com/android/settings/display/ExPlanPreferenceController.java

在Settings模块的ExPlanPreferenceController.java文件中,需要添加以下几行代码,用于实现下拉菜单开关偏好项的控制器,主要负责读取和写入系统属性,以及发送控制广播:

packagecom.android.settings.display;importandroid.content.Context;importandroid.provider.Settings;importandroidx.preference.SwitchPreference;importandroidx.preference.Preference;importandroidx.preference.PreferenceScreen;importcom.android.settings.core.PreferenceControllerMixin;importcom.android.settingslib.core.AbstractPreferenceController;importandroid.content.Intent;importandroid.util.Log;importandroid.os.SystemProperties;publicclassExPlanPreferenceControllerextendsAbstractPreferenceControllerimplementsPreference.OnPreferenceChangeListener{privatestaticfinalStringTAG="ExPlanCtrl";privatestaticfinalbooleanDEBUG=true;privatestaticfinalStringKEY_EXPLAN="ctrl_explan";privatestaticfinalStringSYS_PROP_EXPLAN_ENABLE="persist.sys.explan.enable";privatestaticfinalStringACTION_HIDE_EXPLAN="sys.explan.hide";privatestaticfinalStringACTION_SHOW_EXPLAN="sys.explan.show";publicExPlanPreferenceController(Context context){super(context);}@OverridepublicStringgetPreferenceKey(){returnKEY_EXPLAN;}@OverridepublicbooleanisAvailable(){returntrue;}@OverridepublicvoiddisplayPreference(PreferenceScreen screen){if(!isAvailable()){setVisible(screen,KEY_EXPLAN,false);return;}finalSwitchPreference 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);}}@OverridepublicvoidupdateState(Preference preference){String value =SystemProperties.get(SYS_PROP_EXPLAN_ENABLE,"false");((SwitchPreference) preference).setChecked(value.equals("true"));}@OverridepublicbooleanonPreferenceChange(Preference preference,Object newValue){boolean value =(Boolean) newValue;if(DEBUG){Log.d(TAG,"key value "+ value);}Intent intent =newIntent();if(value){
            intent.setAction(ACTION_SHOW_EXPLAN);}else{
            intent.setAction(ACTION_HIDE_EXPLAN);}
        mContext.sendBroadcast(intent);returntrue;}}

这样就完成了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。

希望本文对你有所帮助,如果有任何问题或建议,请私信和留言。


本文转载自: https://blog.csdn.net/SHH_1064994894/article/details/132483279
版权归原作者 一歲抬頭 所有, 如有侵权,请联系我们删除。

“Android系统 添加动态控制SystemUI状态栏、导航栏和下拉菜单”的评论:

还没有评论