【SystemUI】动态显示或隐藏状态栏及导航栏

发布时间 2023-09-18 17:25:20作者: 安妍

【SystemUI】动态显示或隐藏状态栏及导航栏


平台:RK_TAOBAO_356X    Android11

需求描述:动态切换状态栏与导航栏的显示或隐藏

【解决方案】

通过收发广播进行切换;

> 备注: protected-broadcast  为保护广播,如第三方应用想要接收到系统发送到以下广播,系统需对第三方应用开启相关se权限(以下未涉及,根据不同设备自行抓取)

frameworks\base\packages\SystemUI\AndroidManifest.xml中新增如下,

+ <protected-broadcast android:name="com.dy.intent.systemui.STATUS_BAR_SHOW" ></protected-broadcast>
+ <protected-broadcast android:name="com.dy.intent.systemui.STATUS_BAR_HIDE" ></protected-broadcast>
+ <protected-broadcast android:name="com.dy.intent.systemui.NAVIGATION_BAR_SHOW" ></protected-broadcast>
+ <protected-broadcast android:name="com.dy.intent.systemui.NAVIGATION_BAR_HIDE" ></protected-broadcast>

SystemUI\src\com\android\systemui\statusbar\NavigationBarController.java中新增如下,

+ public void removeNavigationBarView(){
+     removeNavigationBar(mDisplayId);
+ }

SystemUI\src\com\android\systemui\statusbar\phone\PhoneStatusBarView.java中修改如下:

+ import android.os.SystemProperties;
@Override
public boolean onTouchEvent(MotionEvent event) {
    ......
-   //return barConsumedEvent || super.onTouchEvent(event);
+   boolean enable = SystemProperties.get("persist.dy.statubar","1").equals("1");
+   return enable ? barConsumedEvent || super.onTouchEvent(event) : enable;
}

SystemUI\src\com\android\systemui\statusbar\phone\StatusBar.java

+ import android.os.SystemProperties;

+ public static final String STATUSBAR_SHOW = "com.dy.intent.systemui.STATUS_BAR_SHOW";
+ public static final String STATUSBAR_HIDE = "com.dy.intent.systemui.STATUS_BAR_HIDE";
+ public static final String NAVIGATION_SHOW = "com.dy.intent.systemui.NAVIGATION_BAR_SHOW";  
+ public static final String NAVIGATION_HIDE = "com.dy.intent.systemui.NAVIGATION_BAR_HIDE";
+ private RegisterStatusBarResult controlResult;

protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
    ......
    mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
    mNotificationLogger.setHeadsUpManager(mHeadsUpManager);        
+   controlResult = result;
+   try {
+       boolean showNav = SystemProperties.get("persist.dy.statubar.naviga","1").equals("1");
+       if (showNav) {
+           createNavigationBar(result);
+       }
+   } catch (Exception ex) {
+       if (DEBUG) Log.e(TAG, "Exception: " + ex);
+   }
    ......  
}

@VisibleForTesting
protected void registerBroadcastReceiver() {
    ......
+   filter.addAction(STATUSBAR_SHOW);
+   filter.addAction(STATUSBAR_HIDE);
+   filter.addAction(NAVIGATION_SHOW);
+   filter.addAction(NAVIGATION_HIDE);  
    mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
}

private void inflateStatusBarWindow() {
    ......
+   boolean enable = SystemProperties.get("persist.dy.statubar","1").equals("1");
+   mPhoneStatusBarWindow.setVisibility(enable ? View.VISIBLE : View.GONE);
}

private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
+       else if (STATUSBAR_SHOW.equals(action)) {
+           SystemProperties.set("persist.dy.statubar", "1");          
+           if(mPhoneStatusBarWindow != null){
+               mPhoneStatusBarWindow.setVisibility(View.VISIBLE);
+           }
+       } else if (STATUSBAR_HIDE.equals(action)) {
+           SystemProperties.set("persist.dy.statubar", "0");
+           if(mPhoneStatusBarWindow != null){
+               mPhoneStatusBarWindow.setVisibility(View.GONE);
+           }
+       } else if (NAVIGATION_SHOW.equals(action)) {
+           SystemProperties.set("persist.dy.statubar.naviga", "1");
+           if(controlResult != null && getNavigationBarView() == null){
+               try {
+                   createNavigationBar(controlResult);
+               } catch (Exception ex) {
+                   Log.e(TAG, "NAVIGATION_SHOW:exception = " + ex);
+               }
+           }                    
+       } else if (NAVIGATION_HIDE.equals(action)) {
+           SystemProperties.set("persist.dy.statubar.naviga", "0");
+           if(getNavigationBarView() != null){
+               mNavigationBarController.removeNavigationBarView();
+           }                
+       }
    }

拓展:

如上方式处理的广播,如果需要提供广播接口给三方apk,有两种方案:

1、三方apk具有系统签名,可直接按常规发送;

2、三方apk无系统签名,则需要将如上新增的广播处理放到新增静态注册的广播中处理,然后通过如下方式提供给客户:

private void sendBroadcastToSystem(String action){
    Intent intent = new Intent(action);
    intent.setComponent(new ComponentName(pkgname, clsname));
    sendBroadcast(intent);
}