Tuesday, July 17, 2012

Preventing status bar expansion - Disable Notification Bar

Use your phone for just about any length of time, and you'll notice that little icons pop up and sit on the top-most gray bar on your phone. This is known as the Notification Bar, though it's sometimes referred to as the "Status Bar" or "System Status Bar" in Android developer documents

Here, we will see, whether we can play with this status bar or not.
Is there anyway to prevent users from sliding the status bar (expand) or collapsing back?
I'm trying out a lockscreen replacement and seems like it's a must-have feature. Is there any possible way to do it without requiring root privileges?

Answer is Yes, it possible in some how. - 


This actually can be done via a little hack, but requires the permissionandroid.permission.SYSTEM_ALERT_WINDOW:

What you do is add a view the exact size of the status bar directly to the WindowManager with the certain parameters that covers the status bar and prevents it from receiving touch events

View disableStatusBar = new View(context);
WindowManager.LayoutParams handleParams = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.FILL_PARENT,
    <height of the status bar>,
    // This allows the view to be displayed over the status bar
    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
    // this is to keep button presses going to the background window
    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,
    PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP;
context.getWindow().addView(view, params);


This will basically create a transparent view over the status bar that will receive all the touch events and block the events from reaching the status bar and therefore prevents it from being expanded.
NOTE: This code is untested, but the concept works.
 I can confirm. With a few tweaks, call to system resources to retrieve the exact height, and default fallbacks this work like a charm.

Other Post I found - 

First of all, it's impossible to modify the Status Bar if your app is not signed with the phone's rom certified, if you try to modify it you'll get an Security Exception.
The only way I've found after several hours of work is by overriding the "onWindowFocusChanged" method of the activity and when it loses the focus (maybe the user has touched the notifications bar), force to collapse the StatusBar, here is the code (working on a Defy+ 2.3.5).
Update: You will have to use your own custom Alert Dialog by overriding it their onWindowFocusChanged method too, because Alert Dialogs have their own focus.


public void onWindowFocusChanged(boolean hasFocus)
{
        try
        {
           if(!hasFocus)
           {
                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)
        {
        }
}


This method is such a hack, it lets the user expand the status bar to a certain extent then pulls it back up. Its better to just cover the status bar with a View that consumes all onTouchEvents.

It works just fine on ANY API level 4 and up. You use the WindowManager class which has NOT changed its fundamental implementation in a while

OR, You can totally hide the status bar through below code - 

requestWindowFeature(Window.FEATURE_NO_TITLE);

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                            WindowManager.LayoutParams.FLAG_FULLSCREEN);


This will make the app fullscreen and hence hide the status bar. I do not want this as this will bring more work for me by having to implement by own status bar.

Some of the interesting information I found at stack is - 
Short answer: this is impossible!
Now should you be interested to know why this is impossible:
There are two permissions for manipulating the system status bar, EXPAND_STATUS_BAR andSTATUS_BAR. The former can be requested by any application, but the later is reserved for applications signed with the platform signature (system applications, not third-party). It is possible to expand/ collapse the system status bar (see "How to open or expand status bar through intent?") but note that reflection is required because the StatusBarManager class is not part of the SDK. The disable method, which is used by the Android dialer to prevent the status bar from being expanded, cannot be accessed by an application without the aforementioned STATUS_BAR permission.
Sources: personal experience :-)

 Conclusion - 


Not possible after going other blogs and discussion in google group.


“possible to read drag in status bar notification” , google group discussion, and got info that this is not possible