Prevent status bar for appearing android (modified) Prevent status bar for appearing android (modified) android android

Prevent status bar for appearing android (modified)


We could not prevent the status appearing in full screen mode in kitkat devices, so made a hack which still suits the requirement ie block the status bar from expanding.

For that to work, the app was not made full screen. We put a overlay over status bar and consumed all input events. It prevented the status from expanding.

note:

  • customViewGroup is custom class which extends anylayout(frame,relative layout etc) and consumes touch event.
  • to consume touch event override the onInterceptTouchEvent method ofthe view group and return true

Updated

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

customViewGroup implementation

Code :

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);


In Android M you have to get an extra permission for making overlays. android.permission.SYSTEM_ALERT_WINDOW is not enough! So I used the code from the answer of Abhimaan within disableStatusBar() and had to make an intent to open the right settings dialog. I also added removing view in onDestroy() in order to enable status bar when the app exits. I also reduced the overlay height to 40 as it seems to be enough. Code works with 5.1 and 6.0 here.

public static final int OVERLAY_PERMISSION_REQ_CODE = 4545;protected CustomViewGroup blockingView = null;@Overrideprotected void onDestroy() {    super.onDestroy();    if (blockingView!=null) {        WindowManager manager = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));        manager.removeView(blockingView);    }}@Overrideprotected 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();        }}@Overrideprotected 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);}


For a project I worked on I had found a solution for this but it took a long time. Various threads on Stackoverflow and elsewhere helped me to come up with it. It was a work around on Android M but it worked perfectly. As someone asked for it so I thought I should post it here if it can benefit anyone.

Now that its been a while, I don't remember all the details, but the CustomViewGroup is the class which overrides the main ViewGroup, and detects that a user has swiped from top to show the status bar. But we didn't want to show it, so the user's intercept was detected and any further action was ignored, i.e. Android OS won't get a signal to open the hidden status bar.

And then the methods to show and hide the status bar are also included which you can copy/paste as is in your code where you want to show/hide the status bar.

/** * 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);}