可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to overlay android status bar. In my case it is on top. I do not want to overlay or hide navigation bar.
Note: Solution must work on android 4.2.2+. I prefer answers for non-rooted device.
I have searched many SO questions and answers, but none works on 4.2.2.
Below is my code, but it does not consume touch events. That's why status bar opens its panel. And I do not want this.
@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 main activity I start service:
startService(new Intent(this, StatusBarService.class));
And permission is added in AndroidManifest.xml:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
And now proof it can be done and it works on 4.2.2: Play Google - MobiLock
How?
Screenshots:

回答1:
After try&repeat, this 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 on 4.2.2 and 4.4.2
回答2:
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 any layout(frame,relative layout etc) and consumes touch event.
- to consume touch event override the onInterceptTouchEvent method of the 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);
Note not rooting required
回答3:
Can't you put your app in a notitlebar theme [shouldn't remove the navigation bar] and implement your own view on top that mimics the notification bar look as a container and the rest of the contents would be fragments ?