当前位置: 首页 > article >正文

RK3576 Android14 状态栏和导航栏增加显示控制功能

  问题背景:

     因为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、设置-->显示菜单里的效果如下图


http://www.kler.cn/a/506484.html

相关文章:

  • 金融项目实战 05|Python实现接口自动化——登录接口
  • 通过maven命令上传jar包至nexus v3.7.1
  • 【leetcode 13】哈希表 242.有效的字母异位词
  • 探索 Transformer²:大语言模型自适应的新突破
  • 你喜欢用什么编辑器?
  • C 语言标准库函数——strtol函数
  • 玩转大语言模型——使用graphRAG+Ollama构建知识图谱
  • Linux Top 命令 load average 指标解读
  • 正式开源,Doris Operator 支持高效 Kubernetes 容器化部署方案
  • JS宏进阶: 工厂函数与构造函数
  • 【深度学习】PyTorch :调用残差网络(ResNet)
  • nginx反向代理http 和 https(案例)
  • 域名劫持是怎么回事?怎么解决?
  • docker安装和测试redis步骤
  • 8.BMS SOC的算法总结
  • 【20250115】Nature子刊:柔性生物传感与深度学习结合的上肢运动增强外骨骼机器人...
  • 【Rust自学】12.4. 重构 Pt.2:错误处理
  • 酷柚易汛ERP 2025-01-16系统升级日志
  • 【C++ 类和对象 进阶篇】—— 逻辑森林的灵动精灵,舞动类与对象的奇幻圆舞曲
  • elrond32
  • QT跨平台应用程序开发框架(3)—— 信号和槽
  • 【深度学习】关键技术-优化算法(Optimization Algorithms)详解与代码示例
  • shell练习(3)
  • SQL-leetcode—626. 换座位
  • opencv_图像处理_去噪声_采用中值滤波
  • 设计模式相关面试