Android13 动态设置状态栏显示/隐藏

项目场景:

Android 13 EDLA项目双桌面系统,原生Launcher3需要显示状态栏和导航栏,切换到自定义的Launcher时需要隐藏状态栏和导航栏,默认全屏模式。

问题描述

1.设置config参数默认不显示导航栏方式无法做到动态设置的需求。

设置状态栏高度为0dip

frameworks/base/core/res/res/values/dimens.xml

<resources>  
        <dimen name="status_bar_height">0dip</dimen>  
</resources>

默认不显示导航栏

frameworks/base/core/res/res/values/config.xml

<resources> 
	<bool name-"Config_showlavigationBar">falsec/bool> 
</resources>

2.应用中设置全屏模式方式,需要每个应用适配,修改范围过大。

由于1、2方式无法满足项目需求,需要修改SystemUI代码实现。


解决方案:

1. 动态隐藏导航

由于需求项目是双桌面系统,桌面切换通过应用禁用/启用对应的Launcher应用来实现Launcher唯一。禁用原生Launcher3时就可以同步隐藏底部的状态栏,启动原生Launcher3时额可以显示底部状态栏;所以禁用Launcher3即可实现动态控制导航栏显示或隐藏。

adb禁用/启动应用指令

adb shell pm disable-user <package_name> //禁用
adb shell pm enable <package_name>  //启用

代码实现应用禁用/启用

 PackageManager pm = mContext.getPackageManager();
 pm.setApplicationEnabledSetting("com.android.launcher3", PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);//启用Launcher3

 pm.setApplicationEnabledSetting("com.android.launcher3", PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER, 0);//禁用Launcher3

禁用/启用Launcher3时可以同步设置默认Launcher。

    private void setDefaultLauncher(String packageName) {
        PackageManager pm = getContext().getPackageManager();
        ResolveInfo currentLauncher = getCurrentLauncher();

        List<ResolveInfo> packageInfos = getResolveInfoList();

        ResolveInfo futureLauncher = null;

        for (ResolveInfo ri : packageInfos) {
            if (!TextUtils.isEmpty(ri.activityInfo.packageName) && !TextUtils.isEmpty(packageName)
                    && TextUtils.equals(ri.activityInfo.packageName, packageName)) {
                futureLauncher = ri;
            }
        }
        if (futureLauncher == null) {
            return;
        }

        pm.clearPackagePreferredActivities(currentLauncher.activityInfo.packageName);
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_MAIN);
        intentFilter.addCategory(Intent.CATEGORY_HOME);
        intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
        ComponentName componentName = new ComponentName(futureLauncher.activityInfo.packageName,
                futureLauncher.activityInfo.name);
        ComponentName[] componentNames = new ComponentName[packageInfos.size()];
        int defaultMatch = 0;
        for (int i = 0; i < packageInfos.size(); i++) {
            ResolveInfo resolveInfo = packageInfos.get(i);
            componentNames[i] = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
            if (defaultMatch < resolveInfo.match) {
                defaultMatch = resolveInfo.match;
            }
        }
        pm.clearPackagePreferredActivities(currentLauncher.activityInfo.packageName);
        pm.addPreferredActivity(intentFilter, defaultMatch, componentNames, componentName);
    }

2.动态隐藏状态栏

通过广播方式动态控制状态栏

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java

private static final String ACTION_HIDE_STATUS_BAR = "com.systemui.statusbar.hide";
private static final String ACTION_SHOW_STATUS_BAR = "com.systemui.statusbar.show";



 @VisibleForTesting
    protected void registerBroadcastReceiver() {
        IntentFilter filter = new IntentFilter();
       ....
       //注册显示/隐藏广播
+      filter.addAction(ACTION_HIDE_STATUS_BAR);
+      filter.addAction(ACTION_SHOW_STATUS_BAR);
       mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
		....
    }


.....

 @Override
    public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
        makeStatusBarView(result);
++        mStatusBarWindowController.attach();
          mNotificationShadeWindowController.attach();
--        mStatusBarWindowController.attach();
    }

.....

  private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
          .....
++    		else if (ACTION_SHOW_STATUS_BAR.equals(action)) {
				//显示状态栏				
++         		mStatusBarWindowController.showStatusBar();
++     		} else if (ACTION_HIDE_STATUS_BAR.equals(action)) {
				//隐藏状态栏
++        		 mStatusBarWindowController.hideStatusBar();
++    	 	}
		  ....
            Trace.endSection();
        }
    };

hideStatusBar / showStatusBar具体代码如下

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java

  private void apply(State state,boolean isHideStatus) {
        if (!mIsAttached) {
            return;
        }
        applyForceStatusBarVisibleFlag(state);
        if (!isHideStatus){
            applyHeight(state);
        }
        if (mLp != null && mLp.copyFrom(mLpChanged) != 0) {
            mWindowManager.updateViewLayout(mStatusBarWindowView, mLp);
        }
    }

 public void showStatusBar(){
        apply(mCurrentState);
        mStatusBarWindowView.setVisibility(View.VISIBLE);
    }

    
    public void hideStatusBar(){
        mStatusBarWindowView.setVisibility(View.GONE);
        mLpChanged.height = 0;
        for (int rot = Surface.ROTATION_0; rot <= Surface.ROTATION_270; rot++) {
            mLpChanged.paramsForRotation[rot].height = 0;
        }
        apply(mCurrentState,true);
    }

参考:Android11.0隐藏状态栏及导航栏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值