android - 全屏 TYPE_ACCESSIBILITY_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;
}
});
}
现在,问题是,我如何内省或找到此覆盖下方的窗口?即使在onAccessibilityEvent
回调中,我也只得到了这个覆盖窗口。getWindows()总是有一个size of 1
. 它不是驳斥了上面的断言TYPE_ACCESSIBILITY_OVERLAY
吗?
相关信息:为了接收覆盖上的触摸事件,我在服务设置中禁用了 touchExplorationMode
android:canRequestTouchExplorationMode="false"
解决方案
您似乎缺少的是配置中的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"
/>
在服务连接上:
@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;
}
});
}
编辑:
添加FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
以完成全屏并删除canRequestTouchExplorationMode
,因为不应包含与此属性关联的标志,因此无用。
推荐阅读
- typescript - 实习生 Selenium 错误:BUG:收到无效会话的 suiteEnd
- javascript - 是否可以使用媒体源扩展显示来自网络摄像头的视频块?
- python - 用零个 python pandas 填充 nan
- android - How to take value from dropdown and display as text on screen?
- cordova - 离子 - 显示时避免白色键盘背景
- c# - 当两个表中都不存在 ID 时使用 Linq 连接实体框架表
- vue.js - VueJS:setInterval 方法无法正常工作
- android - :app:transformDexArchiveWithExternalLibsDexMergerForDebug 后 installnig react-native-maps
- python - Qt - VBoxLayout 中 addWidget 的默认对齐方式
- android-mediacodec - 为什么 MediaCodec.reset() 会生成 java.lang.IllegalStateException