问题背景:
因为RK3576 Android14用户需要手动控制状态栏和导航栏显示隐藏控制,包括对锁屏后下拉状态栏的屏蔽,在设置功能里增加此功能的控制,故参考一些博客完成此功能,以下是具体代码路径的修改内容。
解决方案:
1、 修改系统默认配置
代码位置:device/rockchip/rk3576/device.mk
PRODUCT_PROPERTY_OVERRIDES += \
+ persist.sys.statusbar.enable=true \
+ persist.sys.navigationbar.enable=true
2、修改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/phone/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、设置-->显示菜单里的效果如下图