SystemUI 怎样给应用提供禁止下拉状态栏接口?

2019-04-24  本文已影响0人  忘冻鱼

不积跬步无以至千里

        在系统开发的时候常常会遇到某些场景是不让下拉状态栏的,因为上边会有一些控制开关,还有一些通知的跳转,这样就会规避到这个原则,比如开机向导中让你为了一些安全措施必须完成的某些步骤等等.

        在这里系统其实已经为你提供了一个Api接口了,如下:

    StatusBarManager mStatusBarManager = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);

    // Disable statusbar pull-down

    mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);

          不过细心的童鞋点进Api中一看这个接口是@Hide的方法,因此对于一些三方的app是不让用的,这个方法好像反射也不行.那怎么办呢?咱们也不能把这个释放开啊,所以还是寻找其它解决办法.因此其实可以通过它控制的逻辑找出突破口.

          其实有兴趣的同学可以看一下我另一篇文章就是对这api的追踪代码,文章链接如下:

            https://blog.csdn.net/WDYShowTime/article/details/83782933

            其中文章有对这个disable的调用是通过StatusBarManagerService,然后其实根本的控制是想用户通过这个Manager然后通过这个disable等各种操作对SystemUI中的下拉的状态栏进行控制,所以看一下这个控制到SystemUI以后是在目录如下:

vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java

    /**

        * State is one or more of the DISABLE constants from StatusBarManager.

        */

        @Override

        public void disable(int state1, int state2, boolean animate) {

            animate &= mStatusBarWindowState != WINDOW_STATE_HIDDEN;

            mDisabledUnmodified1 = state1;

            mDisabledUnmodified2 = state2;

            final int old1 = mDisabled1;

            final int diff1 = state1 ^ old1;

            mDisabled1 = state1;

            ...

其中你设置的disable的传递给了mDisabled1这个int值了,其中你会发现其中状态栏的面板会通过在这,目录如下:

vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java

    @Override

        public boolean onTouchEvent(MotionEvent event) {

            // Allow subclasses to implement enable/disable semantics

            if (!panelEnabled()) {

                if (event.getAction() == MotionEvent.ACTION_DOWN) {

                    Log.v(TAG, String.format("onTouch: all panels disabled, ignoring touch at (%d,%d)",

                            (int) event.getX(), (int) event.getY()));

                }

                return false;

            }

其实可以看出当panelEnabled这个不可用的时候就return false,这个PanelBar是状态栏的父View,这样面板的下拉就被"消费"了.

其实看一下这个panelEnabled()的逻辑就和上边对应起来了,其实这边panelEnabled最终也是调用的StatusBar中的panelEnabled方法,目录如下:

vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java

    public boolean panelsEnabled() {

            return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0 && !ONLY_CORE_APPS;

        }

因此,返回false的时候就拦截了,因此咱们这里可以通过某个值比如SystemProperties或者Settings.system中的数据库,或者某个应用的数据库等,咱们通过某个值来进行一个处理就行了,如下:

public boolean panelsEnabled() {

            //[add] start

            if (SystemProperties.getBoolean("persist.status.bar.enable", false)) {

                return false;

            }

            // end

            return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0 && !ONLY_CORE_APPS;

        }

具体的逻辑你可以怎么进行判断你都可以,false的时候就会进行拦截不能下拉了.

重要的事说两边,其中关于上边的api的调用流程文章URL: https://blog.csdn.net/WDYShowTime/article/details/83782933

上一篇下一篇

猜你喜欢

热点阅读