打开时关闭状态栏:Android

时间:2014-11-11 18:07:24

标签: android statusbar

我试图想出一些方法来禁用状态栏而不完全隐藏它。这是禁止第三方应用中的状态栏的尝试。现在,我想在我自己的应用程序中禁用它,然后最终创建一个后台服务,看看我是否可以在其他应用程序中这样做。我正在创建的应用程序是一个儿童操作系统,我正在尝试开发一个封闭的系统。

这是我尝试过的。我最初的想法是监视何时访问状态栏然后关闭它。

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    Log.i(TAG, "onWindowFocusChanged()");
    try {
        if (!hasFocus) {
            Log.d(TAG, "close status bar attempt");
            Object service = getSystemService("statusbar");
            Class<?> statusbarManager = Class
                    .forName("android.app.StatusBarManager");
            Method collapse = statusbarManager.getMethod("collapse");
            collapse.setAccessible(true);
            collapse.invoke(service);
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

这是我使用的方法。它适用于检测何时访问状态栏,但是一旦它具有焦点,它就不会关闭状态栏。我错过了什么?提前谢谢。

3 个答案:

答案 0 :(得分:4)

我找到了问题的答案。首先,我错过了以下许可

<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />

有了这个权限,以下代码现在可以正常运行。

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    Log.i(TAG, "onWindowFocusChanged()");
    try {
        if (!hasFocus) {
            Log.d(TAG, "close status bar attempt");
            //option 1
            int currentApiVersion = android.os.Build.VERSION.SDK_INT;
            Object service = getSystemService("statusbar");
            Class<?> statusbarManager = Class
                    .forName("android.app.StatusBarManager");

            if (currentApiVersion <= 16) {
                Method collapse = statusbarManager.getMethod("collapse");
                collapse.setAccessible(true);
                collapse.invoke(service);
            } else {
                Method collapse = statusbarManager.getMethod("collapsePanels");
                collapse.setAccessible(true);
                collapse.invoke(service);
            }
            // option 2
            Intent it = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
            mContext.sendBroadcast(it); 

        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

如果你注意到,还有第二种选择,我发现它运作良好。如果要使用选项2,则可以注释掉选项1,反之亦然。两者都做了同样的事情,虽然我认为选项2更好。

Intent it = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mContext.sendBroadcast(it); 

我发现的唯一一个失败是关闭时它很慢(呃)。但是,这两种方法都可以快速崩溃,无法单击状态栏中的任何通知或选项。希望这对其他人有帮助。祝你好运,干杯!

答案 1 :(得分:1)

我也在做同样的事情。使用Android 5.0 Lolipop,他们发布了Screen Pinning模式(基本上是Kiosk模式),它做了一些事情:

  • 状态栏为空白,隐藏用户通知和状态信息。
  • 隐藏了主页和最近的应用程序按钮。
  • 其他应用无法启动新活动。
  • 当前的应用程序可以启动新活动,只要这样做不会创建新任务。
  • 当设备所有者调用屏幕固定时,用户将保持对应用程序的锁定,直到应用程序调用stopLockTask()。
  • 如果屏幕固定是由另一个非设备所有者的应用程序或由用户直接进行的活动,则用户可以通过同时按住“后退”和“最近”按钮退出。

您可以在Android 5.0 Lolipop release documentation

中进一步了解相关信息

但是,如果您正在寻找更具控制性的解决方案,那么您可能需要创建自定义ROM。以下是制作Kiosk应用程序的一个很好的概述(也需要禁用状态栏)。

Developing Kiosk Mode Applications in Android Tutorial

答案 2 :(得分:0)

如果有人仍在寻找这样的解决方案,那么这里有一个更新的答案:https://developer.android.com/training/system-ui/immersive.html

对我来说,我在onResume()方法中添加了以下内容:

View decorView = getWindow().getDecorView();
    int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
    decorView.setSystemUiVisibility(uiOptions);

这允许状态栏保持隐藏,但用户仍然可以通过滑动屏幕边缘来访问它。然后在几秒钟不活动后,它会崩溃并再次消失!