Overlay status bar on android 4.2.2+
I want to overlay android status bar. In my case, it's on top. I don't want to overlay or hide the navigation bar.
Note . The solution should work on android 4.2.2+. I prefer the answers for undisturbed devices.
I have searched a lot of questions and answers, but none works in 4.2.2.
Below is my code, but it doesn't use touch events. Therefore, the status bar opens the panel. And I don't want that.
@Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
int statusBarHeight = (int) Math.ceil(25 * getResources().getDisplayMetrics().density);
overlay = new Button(this);
overlay.setBackgroundColor(Color.GREEN);
overlay.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("StatusBar", "touched");
return false;
}
});
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FILL_PARENT,
statusBarHeight,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH|
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.RIGHT;
windowManager.addView(overlay, params);
}
@Override
public void onDestroy() {
super.onDestroy();
if (overlay != null) windowManager.removeView(overlay);
}
In the main activity, I start the service:
startService(new Intent(this, StatusBarService.class));
And the permission is added to AndroidManifest.xml:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
And now it can be done and it works on 4.2.2: Play Google - MobiLock
How?
Screenshots
source to share
After trying to repeat this it did it for me:
int statusBarHeight = (int) Math.ceil(25 * getResources().getDisplayMetrics().density);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.FILL_PARENT,
statusBarHeight,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
It works with 4.2.2 and 4.4.2
source to share
We weren't able to prevent the status from showing up in full screen mode on kitkat devices, so we made a hack that still meets the requirement i.e. block status bar expansion.
For this, the app was not in full screen mode. We put an overlay on top of the status bar and consume all input events. This prevented the status expansion.
Note:
- customViewGroup is a custom class that extends any layout (frame, relative layout, etc.) and consumes the touch event.
- to use the touch event, override the onInterceptTouchEvent method of the view group and return true
Update
<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);
Please note that no root is required
source to share