问题背景:
因为RK3576 Android14用户需要手动控制状态栏和导航栏显示隐藏控制,包括对锁屏后下拉状态栏的屏蔽,在设置功能里增加此功能的控制,故参考一些博客完成此功能,以下是具体代码路径的修改内容。
解决方案:
1、修改系统默认配置
代码位置:device/rockchip/rk3576/device.mk
PRODUCT_PROPERTY_OVERRIDES += \ + persist.sys.statusbar.enable=true \ + persist.sys.navigationbar.enable=true2、修改SystemUI
android/frameworks/base/packages/SystemUI/AndroidManifest.xml
<protected-broadcast android:name="com.android.systemui.action.ACTION_LAUNCH_MEDIA_OUTPUT_BROADCAST_DIALOG" /> + <!-- For statusbar show or not --> + <protected-broadcast android:name="com.systemui.statusbar.show" /> + <protected-broadcast android:name="com.systemui.statusbar.hide" /> + <!-- For NavigationBar show or not --> + <protected-broadcast android:name="com.systemui.navigationbar.show" /> + <protected-broadcast android:name="com.systemui.navigationbar.hide" /> <application android:name=".SystemUIApplication" android:persistent="true"frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
import android.content.res.Resources; public static final int FADE_KEYGUARD_DURATION = 300; public static final int FADE_KEYGUARD_DURATION_PULSING = 96; + private static final String ACTION_HIDE_STATUS_BAR = "com.systemui.statusbar.hide"; + private static final String ACTION_SHOW_STATUS_BAR = "com.systemui.statusbar.show"; + private static final String ACTION_HIDE_NAVIGATION_BAR = "com.systemui.navigationbar.hide"; + private static final String ACTION_SHOW_NAVIGATION_BAR = "com.systemui.navigationbar.show"; + public static final String SYS_PROPERTY_STATUS_BAR = "persist.sys.statusbar.enable"; + public static final String SYS_PROPERTY_NAVIGATION_BAR = "persist.sys.navigationbar.enable"; @Override public void start() { mScreenLifecycle.addObserver(mScreenObserver); .......................... mConfigurationController.addCallback(mConfigurationListener); mBatteryController.observe(mLifecycle, mBatteryStateChangeCallback); mLifecycle.setCurrentState(RESUMED); + //根据系统设置参数控制状态栏显示隐藏 + boolean statusBarDisplay=SystemProperties.getBoolean(SYS_PROPERTY_STATUS_BAR, false); + Log.d(TAG, "----------default---------statusBarDisplay:"+statusBarDisplay); + if (!statusBarDisplay) { + mStatusBarWindowController.setBarVisibility(View.GONE); + } } mAccessibilityFloatingMenuController.init(); ........................... // ================================================================================ protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) { ....................... mStatusBarInitializer.initializeStatusBar( mCentralSurfacesComponent::createCollapsedStatusBarFragment); mStatusBarTouchableRegionManager.setup(this, getNotificationShadeWindowView()); + //createNavigationBar(result); + //根据系统设置参数控制导航栏显示隐藏 + boolean navigationBarDisplay=SystemProperties.getBoolean(SYS_PROPERTY_NAVIGATION_BAR, false); + Log.d(TAG, "----------default---------navigationBarDisplay:"+navigationBarDisplay); + if (navigationBarDisplay) { + createNavigationBar(result); + } //============================================================================== @VisibleForTesting protected void registerBroadcastReceiver() { IntentFilter filter = new IntentFilter(); .................. + 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(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG); context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); //======================================================================== private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { .............. } else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) { mQSPanel.showDeviceMonitoringDialog(); }//状态栏和导航栏显示隐藏控制 + else if (ACTION_HIDE_NAVIGATION_BAR.equals(action)) { + Log.d(TAG, "---ACTION_HIDE_NAVIGATION_BAR---"); + SystemProperties.set(SYS_PROPERTY_NAVIGATION_BAR, "false"); + mNavigationBarController.onDisplayRemoved(mDisplayId); + } else if (ACTION_SHOW_NAVIGATION_BAR.equals(action)) { + Log.d(TAG, "---ACTION_SHOW_NAVIGATION_BAR---"); + SystemProperties.set(SYS_PROPERTY_NAVIGATION_BAR, "true"); + mNavigationBarController.onDisplayReady(mDisplayId); + } else if (ACTION_HIDE_STATUS_BAR.equals(action)) { + Log.d(TAG, "---ACTION_HIDE_STATUS_BAR---"); + SystemProperties.set(SYS_PROPERTY_STATUS_BAR, "false"); + mStatusBarWindowController.setBarVisibility(View.GONE); + } else if (ACTION_SHOW_STATUS_BAR.equals(action)) { + Log.d(TAG, "---ACTION_SHOW_STATUS_BAR---"); + SystemProperties.set(SYS_PROPERTY_STATUS_BAR, "true"); + mStatusBarWindowController.setBarVisibility(View.VISIBLE); } } };frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
+ /** + * Sets the visibility of the status bar window. + * 设置状态栏的可见性 + */ + public void setBarVisibility(int visibility) { + mStatusBarWindowView.setVisibility(visibility); + }frameworks/base/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java 修改三个方法此类主要是锁屏后状态栏处理
import android.os.SystemProperties; import com.android.systemui.statusbar.phone.CentralSurfacesImpl; //=========================================== private void setExpandedHeightInternal(float h) { .................................. if (mExpandedHeight < 1f && mExpandedHeight != 0f && mClosing) { mExpandedHeight = 0f; if (mHeightAnimator != null) { mHeightAnimator.end(); } } mExpandedFraction = Math.min(1f, maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight); + int barState = getBarState(); + //根据系统设置参数控制锁平后面板是否显示 ,禁止对状态栏布局设置 + boolean statusBarDisplay=SystemProperties.getBoolean(CentralSurfacesImpl.SYS_PROPERTY_STATUS_BAR, false); + //非锁屏的状态栏状态栏下拉面板隐藏处理 + if (!statusBarDisplay && barState!=KEYGUARD) { + mExpandedFraction=0; + } mQsController.setShadeExpansion(mExpandedHeight, mExpandedFraction); mExpansionDragDownAmountPx = h; mAmbientState.setExpansionFraction(mExpandedFraction); //==================================================== public final class TouchHandler implements View.OnTouchListener, Gefingerpoken { private long mLastTouchDownTime = -1L; /** @see ViewGroup#onInterceptTouchEvent(MotionEvent) */ @Override public boolean onInterceptTouchEvent(MotionEvent event) { .............................. if (!mQsController.shouldQuickSettingsIntercept(mDownX, mDownY, 0) && mPulseExpansionHandler.onInterceptTouchEvent(event)) { mShadeLog.v("NotificationPanelViewController MotionEvent intercepted: " + "PulseExpansionHandler"); return true; } + //根据系统设置参数控制锁平后面板是否显示 ,拦截触摸事件分发 boolean statusBarDisplay=SystemProperties.getBoolean(CentralSurfacesImpl.SYS_PROPERTY_STATUS_BAR, false); + if (!statusBarDisplay && !isFullyCollapsed() && mQsController.onIntercept(event)) { debugLog("onQsIntercept true"); mShadeLog.v("NotificationPanelViewController MotionEvent intercepted: " + "QsIntercept"); //============================================= @Override public boolean onTouchEvent(MotionEvent event) { .................................... if (mListenForHeadsUp && !mHeadsUpTouchHelper.isTrackingHeadsUp() && !mNotificationStackScrollLayoutController.isLongPressInProgress() && mHeadsUpTouchHelper.onInterceptTouchEvent(event)) { mMetricsLogger.count(COUNTER_PANEL_OPEN_PEEK, 1); } boolean handled = mHeadsUpTouchHelper.onTouchEvent(event); + //根据系统设置参数控制状态栏下拉面板显示隐藏,屏蔽状态了下滑事件 boolean statusBarDisplay=SystemProperties.getBoolean(CentralSurfacesImpl.SYS_PROPERTY_STATUS_BAR, false); + if (statusBarDisplay && !mHeadsUpTouchHelper.isTrackingHeadsUp() && mQsController.handleTouch( event, isFullyCollapsed(), isShadeOrQsHeightAnimationRunning())) { if (event.getActionMasked() != MotionEvent.ACTION_MOVE) { mShadeLog.logMotionEvent(event, "onTouch: handleQsTouch handled event"); .......................................3、修改Settings APP
android/packages/apps/Settings/res/values-zh-rCN/strings.xml
+ <!--状态栏和导航栏开关设置 --> + <string name="ctrl_statusbar">状态栏</string> + <string name="ctrl_navigationbar">导航栏</string> </resources>android/packages/apps/Settings/res/values/strings.xml
+ <!--状态栏和导航栏开关设置 --> + <string name="ctrl_statusbar">StatusBar</string> + <string name="ctrl_navigationbar">NavigationBar</string> </resources>android/packages/apps/Settings/res/xml/display_settings.xml
settings:userRestriction="no_config_brightness"> <intent android:action="com.android.intent.action.SHOW_BRIGHTNESS_DIALOG" /> </com.android.settingslib.RestrictedPreference> + <SwitchPreference + android:key="ctrl_statusbar" + android:title="@string/ctrl_statusbar"/> + <SwitchPreference + android:key="ctrl_navigationbar" + android:title="@string/ctrl_navigationbar"/> <com.android.settings.display.NightDisplayPreference android:key="night_display"android/packages/apps/Settings/src/com/android/settings/DisplaySettings.java
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.search.SearchIndexable; +import com.android.settings.display.StatusBarPreferenceController; +import com.android.settings.display.NavigationBarPreferenceController; import java.util.ArrayList; import java.util.List; controllers.add(new AwEnhanceModePreferenceController(context)); controllers.add(new AwSmartBacklightPreferenceController(context)); controllers.add(new AwColorTemperaturePreferenceController(context)); + controllers.add(new StatusBarPreferenceController(context)); + controllers.add(new NavigationBarPreferenceController(context)); return controllers; }android/packages/apps/Settings/src/com/android/settings/display/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 PreferenceControllerMixin, Preference.OnPreferenceChangeListener { private static final String TAG = "NavigationBarPreferenceController"; private static final String KEY_NAVIGATION_BAR = "ctrl_navigationbar"; public static final String ACTION_HIDE_NAVIGATION_BAR = "com.systemui.navigationbar.hide"; public static final String ACTION_SHOW_NAVIGATION_BAR = "com.systemui.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, true); return; } final SwitchPreference mNavigationBarPreference = screen.findPreference(KEY_NAVIGATION_BAR); if (mNavigationBarPreference != null) { String value = SystemProperties.get("persist.sys.navigationbar.enable", "true"); mNavigationBarPreference.setChecked(value.equals("true")); mNavigationBarPreference.setOnPreferenceChangeListener(this); } } @Override public void updateState(Preference preference) { String value = SystemProperties.get("persist.sys.navigationbar.enable", "true"); Log.d(TAG, "---updateState--- value: " + value); ((SwitchPreference) preference).setChecked(value.equals("true")); } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { boolean value = (Boolean) newValue; Log.d(TAG, "---onPreferenceChange--- 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; } }android/packages/apps/Settings/src/com/android/settings/display/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 PreferenceControllerMixin, Preference.OnPreferenceChangeListener { private static final String TAG = "StatusBarPreferenceController"; private static final String KEY_STATUS_BAR = "ctrl_statusbar"; public static final String ACTION_HIDE_STATUS_BAR = "com.systemui.statusbar.hide"; public static final String ACTION_SHOW_STATUS_BAR = "com.systemui.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, true); return; } final SwitchPreference mStatusBarPreference = screen.findPreference(KEY_STATUS_BAR); if (mStatusBarPreference != null) { String value = SystemProperties.get("persist.sys.statusbar.enable", "true"); mStatusBarPreference.setChecked(value.equals("true")); mStatusBarPreference.setOnPreferenceChangeListener(this); } } @Override public void updateState(Preference preference) { String value = SystemProperties.get("persist.sys.statusbar.enable", "true"); Log.d(TAG, "---updateState--- value: " + value); ((SwitchPreference) preference).setChecked(value.equals("true")); } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { boolean value = (Boolean) newValue; Log.d(TAG, "---onPreferenceChange--- 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; } }4、设置-->显示菜单里的效果如下图