【Android14 添加SystemUI下拉菜单控制按钮】
Android14相对于之前的Android版本(11,12,13)StatusBar.java文件进行了拆分,所以在Android14中StatusBar的许多函数方法等都更换了位置,不过万变不离其宗,我们添加控制按钮的方法和思路也是类似的,本文以添加下拉菜单控制按钮为例,进行定制化修改。
需求:一些应用程序中读取通知但在其他应用程序中我们需要始终锁定下拉菜单,希望添加Drop Menu 控制器用于控制Menu是否正常下拉。
实现思路:
1.Settings模块:在Settings模块中显示菜单添加开关,用于开启和关闭下拉菜单,并发送相应的广播,并写入相应的系统属性。
2.SystemUI模块:添加广播接收器,用于接收控制下拉菜单显示和隐藏的广播,并执行相应的操作。同时添加系统属性读取,用于获取下拉菜单的初始状态。
Settings模块:
1.添加显示字符串,如有多语言需求请自行在该语言包添加
alps/vendor/mediatek/proprietary/packages/apps/MtkSettings/res/values/strings.xml
Drop Down Menu
2.在设置模块的显示菜单display_settings.xml中添加目标按钮的键值和标题以及控制类
alps/vendor/mediatek/proprietary/packages/apps/MtkSettings/res/xml/display_settings.xml
3.在Settings模块的DisplaySettings.java文件中,用于注册我们的控制开关:
alps/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/DisplaySettings.java
--- a/alps/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/DisplaySettings.java +++ b/alps/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/DisplaySettings.java @@ -29,6 +29,7 @@ import com.android.settings.display.TapToWakePreferenceController; import com.android.settings.display.ThemePreferenceController; import com.android.settings.display.VrDisplayPreferenceController; import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.display.ExPlanPreferenceController; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.search.SearchIndexable; @@ -91,6 +92,9 @@ public class DisplaySettings extends DashboardFragment { /// M: add for HDMI settings @{ controllers.add(new HdmiPreferenceController(context)); /// @} + //wjj add + controllers.add(new ExPlanPreferenceController(context)); + //wjj end return controllers; }
4.添加下拉菜单控制类并添加宏控控制控制按钮是否存在
alps/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/display/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"; private static final boolean HX_TS818_BUG_70579 = SystemProperties.getBoolean("ro.hx_ts818_bug_70579", false); public ExPlanPreferenceController(Context context) { super(context); } @Override public String getPreferenceKey() { return KEY_EXPLAN; } @Override public boolean isAvailable() { if(HX_TS818_BUG_70579){ return true; }else{ return false; } } @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; } }
SystemUI模块
1.在SystemUI模块的AndroidManifest.xml文件中声明广播,同时更改其权限让其正常设置其逻辑。
alps/vendor/mediatek/proprietary/packages/apps/SystemUI/AndroidManifest.xml
--- a/alps/vendor/mediatek/proprietary/packages/apps/SystemUI/AndroidManifest.xml +++ b/alps/vendor/mediatek/proprietary/packages/apps/SystemUI/AndroidManifest.xml @@ -19,7 +19,7 @@ @@ -367,6 +367,10 @@ + + + +
2.在SystemUI模块的CentralSurfacesImpl.java(原StatusBar.java)文件中,我们需要添加以下代码,用于声明和初始化一些变量和方法以及逻辑判断:
alps/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
--- a/alps/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/alps/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -298,6 +298,14 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private static final String BANNER_ACTION_SETUP = "com.android.systemui.statusbar.banner_action_setup"; + //wjj add + private static final String ACTION_HIDE_EXPLAN = "sys.explan.hide"; + private static final String ACTION_SHOW_EXPLAN = "sys.explan.show"; + private static final String SYS_PROPERTY_EXPLAN = "persist.sys.explan.enable"; + + protected StatusBarManager mStatusBarManager; + //wjj end + private static final int MSG_OPEN_SETTINGS_PANEL = 1002; private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003; // 1020-1040 reserved for BaseStatusBar @@ -923,6 +931,9 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mUserTracker = userTracker; mFingerprintManager = fingerprintManager; mActivityStarter = activityStarter; + //wjj add + mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE); + //wjj end mLockscreenShadeTransitionController = lockscreenShadeTransitionController; mStartingSurfaceOptional = startingSurfaceOptional; @@ -980,6 +991,15 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { bubbles.setExpandListener(listener); } + //wjj add + public void explan_show() { + mStatusBarManager.disable(StatusBarManager.DISABLE_NONE); + } + public void explan_hide() { + mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND); + } + //wjj end + @Override public void start() { mScreenLifecycle.addObserver(mScreenObserver); @@ -1322,7 +1342,11 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mStatusBarTouchableRegionManager.setup(this, mNotificationShadeWindowView); createNavigationBar(result); - + //wjj add + if (SystemProperties.getBoolean(SYS_PROPERTY_EXPLAN, false)) { + explan_show(); + } + //wjj end if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) { mLockscreenWallpaper = mLockscreenWallpaperLazy.get(); } @@ -1598,6 +1622,10 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { protected void registerBroadcastReceiver() { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + //wjj add + filter.addAction(ACTION_HIDE_EXPLAN); + filter.addAction(ACTION_SHOW_EXPLAN); + //wjj end filter.addAction(Intent.ACTION_SCREEN_OFF); mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL); } @@ -2200,6 +2228,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { } } + @Override public void dump(PrintWriter pwOriginal, String[] args) { IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal); @@ -2384,7 +2413,15 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { } finishBarAnimations(); resetUserExpandedStates(); - } + //wjj add + } 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"); + } + //wjj end Trace.endSection(); } };
end
总结:
后续编译检测达成目标效果,开关开启时正常下拉下拉栏,开关关闭时无法正常使用下拉功能。
如需进一步控制SystemUI状态栏以及导航栏,可以参考以下链接。
Android系统 添加动态控制SystemUI状态栏、导航栏和下拉菜单_android 下拉菜单-CSDN博客