简体   繁体   English

在Android中按下Back或Home按钮时,是否可以使用WindowManager移除覆盖图?

[英]Is possible remove an overlay with WindowManager when press back or home button in android?

I'm trying to find some answer to my question in the site but I don't found anything, and I'm not sure if is possible remove or hide the overlay with windowManager when press back or home button. 我正在尝试在网站上找到我的问题的答案,但是我什么也没找到,并且我不确定在按返回或主页按钮时是否可以使用windowManager删除或隐藏覆盖。

This is that I have now. 这就是我现在拥有的。 I put an overlay using accessibility service that cover all the screen when the user go to setting screen of my app. 当用户转到我的应用程序的设置屏幕时,我使用辅助功能放置了覆盖所有屏幕的覆盖图。 WindowManager show the overlay, but when I try to press back button or home button it doesn't work. WindowManager显示覆盖,但是当我尝试按“后退”按钮或“主页”按钮时,它不起作用。 Seems like is blocked. 好像被阻止了。 Only disappear the overlay when the process of the app is stopped. 仅在应用程序停止运行时才消失叠加层。

Notice that I don't using a activity to show the overlay. 请注意,我没有使用活动来显示叠加层。 I'm using the accessitibilyService to do this task that extends from AccessibilityService. 我正在使用accessitibilyService来执行此从AccessibilityService扩展的任务。

That I want to do is where the user press back or home button, remove the overlay. 我想做的是用户按下“后退”或“主页”按钮,移除覆盖层。

This is my code to show the overlay: 这是我显示覆盖的代码:

private String checkOverlay = "hide"

 WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                    0,
                    PixelFormat.TRANSLUCENT);
            WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);

            overlayRunning.setBackgroundColor(Color.parseColor("#1C1C1C"));
            wm.addView(overlayRunning, params);
checkOverlay = "show";

I've added this method the class: 我在类中添加了此方法:

 @Override
    public boolean onKeyEvent(KeyEvent event) {
        int keyCode = event.getKeyCode();

        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                Log.e(TAG, "Back button??");
                    Log.e(TAG, "Back button??");
                    overlayRunning.setVisibility(View.INVISIBLE);

            case KeyEvent.KEYCODE_HOME:
                Log.e(TAG, "Home button??");

                if(checkOverlay.equals("show")) {
                    WindowManager wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
                    wm.removeViewImmediate(overlayRunning);
                    Intent startMain = new Intent(Intent.ACTION_MAIN);
                    startMain.addCategory(Intent.CATEGORY_HOME);
                    startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(startMain);
                    checkOverlay = "hide";
                }
                return false;
        }
        return super.onKeyEvent(event);
    }

Simply you need to set the windowmanager type to APPLICATION, this way the windowmanager will attach views while the application is opened only, and no need to overlay home or back buttons, check docs here 只需将windowmanager类型设置为APPLICATION,这样windowmanager将仅在打开应用程序时附加视图,而无需覆盖主页或后退按钮,请在此处检查文档

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.TYPE_APPLICATION,
                    0,
                    PixelFormat.TRANSLUCENT);

Removing the view is easy. 删除视图很容易。 I noticed you have set it to invisible, this is an acceptable solution. 我注意到您已将其设置为不可见,这是可以接受的解决方案。 You can also keep a reference to it around and do the following: 您也可以保留对其的引用并执行以下操作:

windowManager.removeView(mYourView);

The problem is going to be detecting the back button press. 问题将是检测到后退按钮的按下。 You cannot do this reliably. 您无法可靠地执行此操作。 You're relying on a hardware expectation, namely that the back button press sends a key event with KEYCODE_BACK, and the OS does not make this guarantee. 您所依赖的是硬件期望,即按下后退按钮会发送带有KEYCODE_BACK的按键事件,而操作系统不对此做出保证。 However, on my Droid turbo the following works: 但是,在我的Droid Turbo上,以下工作有效:

First you need a separate xml file to configure your accessibility service. 首先,您需要一个单独的xml文件来配置可访问性服务。

contents of service_config.xml: service_config.xml的内容:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:canRequestFilterKeyEvents="true"
    android:accessibilityFlags="flagDefault|flagRequestFilterKeyEvents"
    ...
    />

Contents of AndroidManifest.xml: AndroidManifest.xml的内容:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
    <application ...>
        <service ...>
            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/service_config" />
        </service>
    </application>
</manifest>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM