全屏TYPE_ACCESSIBILITY_OVERLAY

Raj*_*eev 3 android accessibility android-overlay

我对 Android 上的辅助功能不太熟悉。在学习课程和文档时,我在课堂TYPE_ACCESSIBILITY_OVERLAY上遇到了这种情况WindowManager

文档(仅相关文字)

例如,如果存在可触摸的全屏辅助功能覆盖层,则辅助功能服务可以对其下方的窗口进行内省,即使它们被可触摸窗口覆盖。

因此,我着手实现这一目标,即全屏辅助功能叠加层,并尝试内省其下方的窗口

扩展AccessibilityService并在调用时添加了我的全屏覆盖onServiceConnected(添加覆盖的灵感来自这里

@Override
protected void onServiceConnected() {
    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    FrameLayout mLayout = new FrameLayout(this);
    WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
    lp.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
    lp.format = PixelFormat.TRANSLUCENT;
    lp.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
    lp.width = WindowManager.LayoutParams.MATCH_PARENT;
    lp.height = WindowManager.LayoutParams.MATCH_PARENT;
    lp.gravity = Gravity.TOP;
    wm.addView(mLayout, lp);

    mLayout.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // Here I'm getting the touch events on the overlay I added
            return false;
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

现在的问题是,我如何内省或找到此覆盖层下方的窗口?即使在onAccessibilityEvent回调中我也只得到这个覆盖窗口。getWindows()始终有一个size of 1. 这不是反驳了上面的断言吗TYPE_ACCESSIBILITY_OVERLAY

相关信息:为了接收覆盖层上的触摸事件,我在服务设置中禁用了 touchExplorationMode

android:canRequestTouchExplorationMode="false"
Run Code Online (Sandbox Code Playgroud)

ran*_*ser 5

您似乎缺少配置中的flagRetrieveInteractiveWindows 。这些属性和窗口布局参数配置应该可以工作,不需要您禁用canRequestTouchExplorationMode以获取事件并getWindows返回您下面的 AccessibilityWindowInfo 实例:

    <?xml version="1.0" encoding="utf-8"?>
    <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
        android:packageNames="test.demo.com.tests"
        android:accessibilityEventTypes="typeAllMask"
        android:accessibilityFlags="flagRetrieveInteractiveWindows|flagReportViewIds|flagIncludeNotImportantViews"
        android:accessibilityFeedbackType="feedbackAllMask"
        android:notificationTimeout="100"
        android:canRetrieveWindowContent="true"
        />
Run Code Online (Sandbox Code Playgroud)

并在服务连接上:

    @Override
    protected void onServiceConnected() {
        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        FrameLayout layout = new FrameLayout(this);

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_FULLSCREEN |
                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
                WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS| 
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.TOP;

        windowManager.addView(layout, params);
        layout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //You can either get the information here or on onAccessibilityEvent                 
                return false;
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

编辑

添加FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS是为了实现全屏,并被删除canRequestTouchExplorationMode,因为不应包含与此属性关联的标志,因此没有用处。