项目场景:
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);
}

176

被折叠的 条评论
为什么被折叠?



