Android 5.0,防止状态栏扩展

标签 android user-interface android-studio android-5.0-lollipop fullscreen

这是一个很老的问题,但我费了好大劲,还是想不出一个可能的解决办法。

目标

其实很简单。我想开发一些全屏应用程序(例如游戏),其中状态栏不会展开,但是用户触摸屏幕。

该应用程序应该能够在 Android 5.0、sdk 21 (Lollipop) 上运行。

到目前为止我做了什么

我找到了 this post ,它描述了如何用吸收触摸事件的 CustomView 覆盖状态栏,但它对我不起作用 ...

我什至更改了 CustomView 的大小,使其覆盖整个屏幕,但它仍然不起作用,甚至无法覆盖我的按钮。

我使用的代码附在下面。在设备上运行时,按钮和状态栏都可以使用 - 没有任何东西被阻止。

我错过了什么吗?

代码

在 AndroidManifest.xml 中:

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:supportsRtl="true"
    android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

在 activity_main.xml 中:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    android:id="@+id/text_show" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click"
    android:id="@+id/button_click"
    android:onClick="changeText"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true" />

在 MainActivity.java 中:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    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);
    setContentView(R.layout.activity_main);
}
boolean key = false;
public void changeText(View view) {
    TextView tv = (TextView) findViewById(R.id.text_show);
    if (key) {
        tv.setText("hahaha");
    } else {
        tv.setText("eroero");
    }
    key = ! key;
}

在 CustomViewGroup 中(从上面的链接复制):

public 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", "**********Intercepted");
        return true;
    }
}

最佳答案

最后我能做的最好的就是使用 Android 5.0 中引入的任务锁定功能。

引用:startLockTask .

该方法的问题:

  1. 除非您有一个助手应用程序向您的全屏应用程序授予锁定任务权限,否则系统会询问用户是否允许锁定。
  2. 锁定后,用户仍然可以使用物理按钮(主页、后退、音量等)。

由于我的 Intent 不是要有自助服务终端模式,所以我不太关心第 2 点。

第 1 点也是可以接受的,但有点烦人,因为每次调用 onResume 时都会(并且应该)询问它。

这可以通过将服务应用程序设置为设备所有者来解决,这会向需要它的应用程序授予权限。但用户必须自己(参见 this answer)执行此操作,这是合理的,否则应用程序将能够完全绑架您的设备。

关于Android 5.0,防止状态栏扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37871420/

相关文章:

android - bundle ArrayList <ArrayList<Integer>>

java - 使用 Android Google Map API(v2) 获取当前位置,但不幸的是应用程序已停止错误

java - MIUI 中的 Internet 连接状态被阻止

c# - 如何在不调整控件大小的情况下将控件居中? (.net Winforms)

java - androidx.appcompat.widget.AppCompatTextView 无法转换为 android.widget.CheckedTextView

android - MapBox:着色器编译失败:错误:有效的 GLSL 但不是 GLSL ES

ios - NSLayoutConstraint layout_Margin 从 iOS 7 到 iOS 8 的变化

java - 如何找到绕另一个圆的圆周旋转的圆的圆周坐标?

android - 当我在 Android Studio 上运行应用程序时, "Choose device"框不显示

java - 关闭 ProgressDialog 时出错 - E/ViewRootImpl : sendUserActionEvent() mView == null