Android 10.0 通过广播控制systemui状态栏动态显示和隐藏功能实现

1.前言

在10.0的系统rom定制化开发中,在某些特定的产品开发中,需要通过接口来控制系统状态栏的显示和隐藏, 所以就需要了解systemui状态栏的显示构造过程,然后通过相关接口来显示和隐藏状态栏,接下来就来 实现相关的功能

2.通过广播控制systemui状态栏动态显示和隐藏功能实现的核心类

frameworks/base/packages/SystemUl/src/com/android/systemui/statusbar/phone/StatusBar.java

3.通过广播控制systemui状态栏动态显示和隐藏功能实现的核心功能分析和实现

在系统SystemUI状态栏中,StatusBar也是继承SystemUI,启动流程和SystemUI一致。并在start的时候添加创建StatusBar相关的view。 我们从StatusBar的start()方法开始看,从这里来分析下Statusbar的加载流程和工作原理 在系统启动的过程中,在SystemServer.java类中,在启动SystemUIService这个服务以后,这个SystemUIService服务会 调用SystemUI类的Start()方法;SystemUI类又是被BaseStatusBar类实现的;PhoneStatusBar类又继承了 BaseStatusBar类,重写了start()方法,因此实际调用的是PhoneStatusBar的start()方法来完成状态栏的启动。

3.1 StatusBar的创建过程分析

systemui其实结构是比较复杂,里面管理各种服务,导航栏,状态栏,近期列表,下拉菜单,关机界面等, 其中以导航栏和状态栏,近期列表用的比较多,也是本博文会重点讲解的内容。从结构上来讲下拉菜单和 状态栏都是属于statusbar,结构树上也是属于顶层的super_status_bar.xml 创建StatusBar :createAndAddWindows() ,并且做一些初始化值。

    public class StatusBar extends SystemUI implements DemoMode,
            ActivityStarter, OnUnlockMethodChangedListener,
            OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
            ColorExtractor.OnColorsChangedListener, ConfigurationListener,
            StatusBarStateController.StateListener, ShadeController,
            ActivityLaunchAnimator.Callback, AmbientPulseManager.OnAmbientChangedListener,
            AppOpsController.Callback {
     
     
    protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
            final Context context = mContext;
            updateDisplaySize(); // populates mDisplayMetrics
            updateResources();
            updateTheme();
     
            inflateStatusBarWindow(context);
            mStatusBarWindow.setService(this);
            mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
     
            // TODO: Deal with the ugliness that comes from having some of the statusbar broken out
            // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
            mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel);
            mStackScroller = mStatusBarWindow.findViewById(R.id.notification_stack_scroller);
            mZenController.addCallback(this);
            NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
            mNotificationLogger.setUpWithContainer(notifListContainer);
     
            mNotificationIconAreaController = SystemUIFactory.getInstance()
                    .createNotificationIconAreaController(context, this, mStatusBarStateController);
            inflateShelf();
            mNotificationIconAreaController.setupShelf(mNotificationShelf);
     
            Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mNotificationIconAreaController);
            // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
            Dependency.get(PluginDependencyProvider.class)
                    .allowPluginDependency(DarkIconDispatcher.class);
            Dependency.get(PluginDependencyProvider.class)
                    .allowPluginDependency(StatusBarStateController.class);
            FragmentHostManager.get(mStatusBarWindow)
                    .addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
                        CollapsedStatusBarFragment statusBarFragment =
                                (CollapsedStatusBarFragment) fragment;
                        statusBarFragment.initNotificationIconArea(mNotificationIconAreaController);
                        PhoneStatusBarView oldStatusBarView = mStatusBarView;
                        mStatusBarView = (PhoneStatusBarView) fragment.getView();
                        mStatusBarView.setBar(this);
                        mStatusBarView.setPanel(mNotificationPanel);
                        mStatusBarView.setScrimController(mScrimController);
     
                        // CollapsedStatusBarFragment re-inflated PhoneStatusBarView and both of
                        // mStatusBarView.mExpanded and mStatusBarView.mBouncerShowing are false.
                        // PhoneStatusBarView's new instance will set to be gone in
                        // PanelBar.updateVisibility after calling mStatusBarView.setBouncerShowing
                        // that will trigger PanelBar.updateVisibility. If there is a heads up showing,
                        // it needs to notify PhoneStatusBarView's new instance to update the correct
                        // status by calling mNotificationPanel.notifyBarPanelExpansionChanged().
                        if (mHeadsUpManager.hasPinnedHeadsUp()) {
                            mNotificationPanel.notifyBarPanelExpansionChanged();
                        }
                        mStatusBarView.setBouncerShowing(mBouncerShowing);
                        if (oldStatusBarView != null) {
                            float fraction = oldStatusBarView.getExpansionFraction();
                            boolean expanded = oldStatusBarView.isExpanded();
                            mStatusBarView.panelExpansionChanged(fraction, expanded);
                        }
     
                        HeadsUpAppearanceController oldController = mHeadsUpAppearanceController;
                        if (mHeadsUpAppearanceController != null) {
                            // This view is being recreated, let's destroy the old one
                            mHeadsUpAppearanceController.destroy();
                        }
                        mHeadsUpAppearanceController = new HeadsUpAppearanceController(
                                mNotificationIconAreaController, mHeadsUpManager, mStatusBarWindow);
                        mHeadsUpAppearanceController.readFrom(oldController);
                        mStatusBarWindow.setStatusBarView(mStatusBarView);
                        updateAreThereNotifications();
                        checkBarModes();
                    }).getFragmentManager()
                    .beginTransaction()
                    .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(),
                            CollapsedStatusBarFragment.TAG)
                    .commit();
            mIconController = Dependency.get(StatusBarIconController.class);
     
            mHeadsUpManager = new HeadsUpManagerPhone(context, mStatusBarWindow, mGroupManager, this,

        }
    .....
    }

在通过广播控制systemui状态栏动态显示和隐藏功能实现的核心功能中,通过上述的分析得知, makeStatusBarView负责状态栏具体创建 1.加载statusbar设备树super_status_bar :inflateStatusBarWindow(context)-->mPhoneStatusBarWindow(mSuperStatusBarViewFactory.getStatusBarWindowView()),这个设备树的根View是StatusBarWindowView 2.CollapsedStatusBarFragment就是作为加载状态栏的Fragment mPhoneStatusBarWindow负责状态栏的显示和隐藏功能,所以具体就需要来通过mPhoneStatusBarWindow来 控制状态栏的显示和隐藏

//add core start
         private void showStatusBar() {
                if (mPhoneStatusBarWindow!=null){
                                   mPhoneStatusBarWindow.setVisibility(View.VISIBLE);
                    }
          }

            private void hideStatusBar() {
                if (mPhoneStatusBarWindow != null){
                        mPhoneStatusBarWindow.setVisibility(View.GONE);
                    }
            }
//add core end
    @VisibleForTesting
    protected void registerBroadcastReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
+        filter.addAction("com.android.action.showstatus");
+        filter.addAction("com.android.action.hidestatus");
        filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
        mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
    }
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (DEBUG) Log.v(TAG, "onReceive: " + intent);
            String action = intent.getAction();
            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
                KeyboardShortcuts.dismiss();
                if (mRemoteInputManager.getController() != null) {
                    mRemoteInputManager.getController().closeRemoteInputs();
                }
                if (mBubbleController.isStackExpanded()) {
                    mBubbleController.collapseStack();
                }
                if (mLockscreenUserManager.isCurrentProfile(getSendingUserId())) {
                    int flags = CommandQueue.FLAG_EXCLUDE_NONE;
                    String reason = intent.getStringExtra("reason");
                    if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
                        flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
                    }
                    mShadeController.animateCollapsePanels(flags);
                }
            } 
//add core start
+         else if("com.android.action.hidestatus".equals(action)) {
+               hideStatusBar(); //隐藏状态栏
+         }
+        else if("com.android.action.showstatus".equals(action)) {
+               showStatusBar(); //显示状态栏
+        }
//add core end
        }
    };

在通过广播控制systemui状态栏动态显示和隐藏功能实现的核心功能中,通过上述的分析得知, 在通过上述增加showStatusBar()和hideStatusBar()显示和隐藏状态栏的方法中,通过注册广播 com.android.action.showstatus和com.android.action.hidestatus来调用相对应的方法来 显示和隐藏状态栏的功能实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安卓兼职framework应用工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值