android 4.2.2+上的覆盖状态栏

时间:2014-09-12 14:25:06

标签: android android-ui statusbar android-4.2-jelly-bean android-launcher

我想覆盖android状态栏。就我而言,它位于顶部。我不想叠加或隐藏导航栏。

注意:解决方案必须适用于Android 4.2.2+。我更喜欢非根设备的答案。

我搜索了许多SO问题和答案,但没有一个适用于4.2.2。

以下是我的代码,但它不会消耗触摸事件。这就是状态栏打开其面板的原因。我不想要这个。

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

在主要活动中,我开始服务:

startService(new Intent(this, StatusBarService.class));

AndroidManifest.xml中添加了权限:

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

现在证明它可以完成,它适用于4.2.2: Play Google - MobiLock

如何吗

截图: enter image description here enter image description here

3 个答案:

答案 0 :(得分:6)

尝试并重复之后,这对我来说是这样的:

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

适用于4.2.2和4.4.2

答案 1 :(得分:2)

我们无法阻止在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);

请注意,不需要生根

答案 2 :(得分:0)

你不能把你的应用放在一个notitlebar主题[不应该删除导航栏]并在顶部实现你自己的视图,模仿通知栏看起来像一个容器,其余的内容将是碎片?