防止出现android的状态栏(修改)

时间:2014-08-13 10:51:57

标签: android statusbar kiosk

我正在实施一个信息亭模式应用程序,我已经成功地使应用程序全屏没有状态栏外观4.3但无法隐藏4.3和4.4中的状态栏,因为状态栏出现在我们向下滑动的顶部屏幕。

我试图通过

全屏显示
  • 在清单
  • 中指定全屏主题
  • 设置窗口标志即setFlags
  • setSystemUiVisibility

可能重复但未找到具体解决方案

Permanently hide Android Status Bar

最后我想要的是,如何在活动中永久隐藏状态栏?在android 4.3,4.4,5,6versions

3 个答案:

答案 0 :(得分:85)

我们无法阻止在kitkat设备中以全屏模式显示状态,因此制作了一个仍然符合要求的黑客攻击,即阻止状态栏扩展。

为此,该应用程序未全屏显示。我们在状态栏上放置了一个叠加层并消耗了所有输入事件。它阻止了地位的扩大。

<强> 注意:

  • customViewGroup是自定义类,可以扩展任何类 布局(框架,相对布局等)并消耗触摸事件。
  • 使用touch事件覆盖onInterceptTouchEvent方法 视图组并返回true

<强>更新

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

<强> customViewGroup implementation

代码:

WindowManager manager = ((WindowManager) getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE));

WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
localLayoutParams.gravity = Gravity.TOP;
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|

            // this is to enable the notification to recieve touch events
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |

            // Draws over status bar
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

    localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
    localLayoutParams.height = (int) (50 * getResources()
            .getDisplayMetrics().scaledDensity);
    localLayoutParams.format = PixelFormat.TRANSPARENT;

    customViewGroup view = new customViewGroup(this);

    manager.addView(view, localLayoutParams);

答案 1 :(得分:17)

在Android M中,您必须获得制作叠加层的额外权限。 android.permission.SYSTEM_ALERT_WINDOW还不够!所以我在disableStatusBar()中使用了Abhimaan的答案中的代码,并且必须打算打开正确的设置对话框。我还添加了删除onDestroy()中的视图,以便在应用退出时启用状态栏。我也将叠加高度减少到40,因为它似乎足够了。代码在这里使用5.1和6.0。

public static final int OVERLAY_PERMISSION_REQ_CODE = 4545;
protected CustomViewGroup blockingView = null;

@Override
protected void onDestroy() {

    super.onDestroy();

    if (blockingView!=null) {
        WindowManager manager = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
        manager.removeView(blockingView);
    }
}


@Override
protected void onCreate(Bundle savedInstanceState) {

        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            if (!Settings.canDrawOverlays(this)) {
                Toast.makeText(this, "Please give my app this permission!", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
            } else {
                disableStatusBar();
            }
        }
        else {
            disableStatusBar();
        }
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
        if (!Settings.canDrawOverlays(this)) {
            Toast.makeText(this, "User can access system settings without this permission!", Toast.LENGTH_SHORT).show();
        }
        else
        { disableStatusBar();
        }
    }
}

protected void disableStatusBar() {

    WindowManager manager = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));

    WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
    localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
    localLayoutParams.gravity = Gravity.TOP;
    localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |

            // this is to enable the notification to receive touch events
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |

            // Draws over status bar
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

    localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
    localLayoutParams.height = (int) (40 * getResources().getDisplayMetrics().scaledDensity);
    localLayoutParams.format = PixelFormat.TRANSPARENT;

    blockingView = new CustomViewGroup(this);
    manager.addView(blockingView, localLayoutParams);
}

答案 2 :(得分:0)

对于我从事的项目,我已经找到了解决方案,但是花了很长时间。 Stackoverflow和其他地方的各种线程帮助我提出了这个建议。这是在Android M上解决的问题,但效果很好。正如有人要求的那样,我想如果它可以使任何人受益,我都应该在这里发布。

现在已经有一段时间了,我不记得所有的细节了,但是CustomViewGroup是覆盖主要ViewGroup的类,并检测到用户已从顶部滑动以显示状态栏。但是我们不想显示它,因此检测到用户的拦截并忽略了任何进一步的操作,即Android OS不会收到打开隐藏状态栏的信号。

然后还包括了用于显示和隐藏状态栏的方法,您可以在要显示/隐藏状态栏的代码中按原样复制/粘贴。

/**
 * This class creates the overlay on the status bar which stops it from expanding.
 */
public static class CustomViewGroup extends ViewGroup {

    public CustomViewGroup(Context context) {
        super(context);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.v("customViewGroup", "********** Status bar swipe intercepted");
        return true;
    }
}

public static void allowStatusBarExpansion(Context context) {
    CustomViewGroup view = new CustomViewGroup(context);
    WindowManager manager = ((WindowManager) context.getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE));
    manager.removeView(view);
}

// Stop expansion of the status bar on swipe down.
public static void preventStatusBarExpansion(Context context) {
    WindowManager manager = ((WindowManager) context.getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE));

    Activity activity = (Activity) context;
    WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
    localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
    localLayoutParams.gravity = Gravity.TOP;
    localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |

            // this is to enable the notification to receive touch events
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |

            // Draws over status bar
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

    localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
    //http://stackoverflow.com/questions/1016896/get-screen-dimensions-in-pixels
    int resId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
    int result = 0;
    if (resId > 0) {
        result = activity.getResources().getDimensionPixelSize(resId);
    }

    localLayoutParams.height = result;

    localLayoutParams.format = PixelFormat.TRANSPARENT;

    CustomViewGroup view = new CustomViewGroup(context);

    manager.addView(view, localLayoutParams);
}