禁止StatusBar展开

前言

最近想写一个小应用,看到要模仿的那个应用,状态栏是拉不下来的,就好像锁屏应用不许下拉状态栏一样,
于是百度了好久,都说需要修改源代码,最后还是选择了简单的java实现。

 
 
  • 1
  • 2
  • 3
这里说一下:
  1. statusbar是由StatusBarManager控制的,但是StatusBarManager安卓默认是不能使用的,这里需要曲线救国;
  2. 没错,救国方案就是java的反射机制!
  3. StatusBarManager的实现在4.2之后就发生了改变,但网上的文章都是4.2之前的,只能说部分能用,所以我写了这文章,hhh。
这里这里不多说,上代码:
    public static final int DISABLE_EXPAND = 0x00010000;//4.2以上的整形标识
    public static final int DISABLE_EXPAND_LOW = 0x00000001;//4.2以下的整形标识
    public static final int DISABLE_NONE = 0x00000000;//取消StatusBar所有disable属性,即还原到最最原始状态

    private void unBanStatusBar() {//利用反射解除状态栏禁止下拉
        Object service = getSystemService("statusbar");
        try {
            Class<?> statusBarManager = Class.forName
                    ("android.app.StatusBarManager");
            Method expand = statusBarManager.getMethod("disable", int.class);
            expand.invoke(service, DISABLE_NONE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void setStatusBarDisable(int disable_status) {//调用statusBar的disable方法
        Object service = getSystemService("statusbar");
        try {
            Class<?> statusBarManager = Class.forName
                    ("android.app.StatusBarManager");
            Method expand = statusBarManager.getMethod("disable", int.class);
            expand.invoke(service, disable_status);
        } catch (Exception e) {
            unBanStatusBar();
            e.printStackTrace();
        }
    }

    private void banStatusBar() {//禁止statusbar下拉,适配了高低版本
        int currentApiVersion = android.os.Build.VERSION.SDK_INT;
        if (currentApiVersion <= 16) {
            setStatusBarDisable(DISABLE_EXPAND_LOW);
        } else {
            setStatusBarDisable(DISABLE_EXPAND);
        }
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

调用时机,banStatusBar方法在onWindowFocusChanged方法调用,即在activity附着在window的时候调用,这个statusbar的disable必须再次设置为none(DISABLE_NONE),因为这个disable方法是全局的,必须没有除去,就算退出应用,状态栏也是不能下拉的,所以我这里选择在onPause方法设置none,代码如下:

    public void onWindowFocusChanged(boolean hasFocus) {
        banStatusBar();
    }

    @Override
    protected void onPause() {
        super.onPause();
        unBanStatusBar();
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在Android 6.0上验证了下,把banStatusBar方法加在onWindowFocusChanged方法中会导致应用退出后,状态栏没有恢复下拉,后面改为加在onResume方法中就不会出现该问题了。

另外验证时添加了System的UID,并使用的系统的平台签名。

这里再贴一个状态栏下拉的方法吧,当记录,也当分享:

    private void expandNotify() {
        int currentApiVersion = android.os.Build.VERSION.SDK_INT;
        try {
            Object service = getSystemService("statusbar");
            Class<?> statusbarManager = Class
                    .forName("android.app.StatusBarManager");
            Method expand = null;
            if (service != null) {
                if (currentApiVersion <= 16) {
                    expand = statusbarManager.getMethod("expand");
                    expand.setAccessible(true);
                    expand.invoke(service);
                } else {
                    expand = statusbarManager
                            .getMethod("expandNotificationsPanel");
                }
                expand.setAccessible(true);
                expand.invoke(service);
            }

        } catch (Exception e) {
        }
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

最后记得添加权限:

    <uses-permission android:name="android.permission.STATUS_BAR"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>
    <!--权限在manifest便签下,application标签之上-->
 
 
  • 1
  • 2
  • 3
  • 4

PS:使用的时候Object service = getSystemService(“statusbar”)这句在android studio中字符串statusbar会出现红色波浪线,不用理会,照样能运行的。

有需要可以看看这个: 
关于statusBarManager的源代码(安卓4.4) - 下载频道 - CSDN.NET http://download.csdn.net/detail/qq_26819733/9602861

17.09.21更新:

Caused by: java.lang.SecurityException: StatusBarManagerService: Neither user 10290 nor current process has android.permission.STATUS_BAR.
 
 
  • 1

想必大家5.0以上都会遇到这个错误,说明真的不能用反射达到禁止下拉状态栏的效果的,因为当前应用申请不到android.permission.STATUS_BAR这个权限,所以反射也不能解决。下这个结论,当结贴吧。起初想研究这个是因为我当时用安卓4.4的手机,同时刚好有个叫“BT戒手机”的app,当时就想研究一下,当时我写代码的时候是成功的,因为用的手机是安卓4.4的,而我现在我用的是安卓5.1的手机,发现此方法已无用。今晚下载了BT戒手机APP试了试,那个APP也是失效的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值