Google TalkBack 服务如何在按钮/文本/图像/等上绘制矩形?

How Google TalkBack service draws Rectangle over buttons/texts/images/etc.?

提问人:Nikoloz Chitashvili 提问时间:5/14/2021 更新时间:4/27/2023 访问量:511

问:

在你开始打字之前,我会说你要写下 、 等的文档。AccessibilityServiceAccessibilityNodeInfo

我已经正确地实现了我的,我什至正确地得到了 -s。AccessibilityServiceAccessibilityEvent

我只关心如何通过用户的点击在视图周围绘制矩形。

到目前为止,我在这方面做了什么:

  • 创建自定义视图类,实现ViewGroup
  • 我添加了(我写的类)作为 with ,byt 调用方法CustomViewViewWindowManager.addView()
  • 我正在通过从重载方法调用来绘制矩形Canvascanvas.drawRect()onDraw()
  • 在屏幕上添加视图时,我使用标志和类型将参数传递到方法中WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCHWindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY.addView()

你可能想知道这里有什么问题..

他们来了:

  1. 使用服务添加新内容时,整个新功能会覆盖屏幕,并且无法访问其他按钮。(除了新添加的图层之外,我真的无法单击任何内容,我认为它被绘制在所有内容之上,并且一切都变得无法单击)CustomViewWindowManagerView
  2. 将自定义视图添加为图层而不是直接围绕某些视图绘制,会导致(或不,我不确切知道)存储用户单击的按钮的错误方向。(当我用矩形绘制相同的矩形时,矩形没有完全显示在视图周围,有些坐标是错误的)event.source.getBoundsInScreen(rect)onAccessibilityEvent(event: AccessibilityEvent)canvas.drawRect(rect, mpaint)

我想让我的绘图矩形像 Google TalkBack 一样。AccessibilityService

Google TalkBack 在视图周围绘制了完美的矩形,但不幸的是,我的矩形没有。

  • 这是我的应用程序绘制矩形的屏幕截图:(单击“9”)

mine screen

  • 这是Google TalkBack点击“9”按钮的屏幕截图:

talkbacks screen

谢谢。

Android Kotlin Canvas OnDraw 辅助功能服务

评论

0赞 cactustictacs 5/14/2021
对你正在做的事情的技术方面没有真正的帮助,但那个矩形看起来正好偏移了视图高度的一半 - 你确定你不只是计算了坐标?
0赞 Nikoloz Chitashvili 5/14/2021
嘿,感谢您的回复!这是 的屏幕截图。我在计算坐标时添加了,但这不适用于其他应用程序:/这也是屏幕截图。奇怪onDraw- this.rectToDraw.height() / 2
0赞 Nikoloz Chitashvili 5/14/2021
但是添加在计算器上就像一个魅力。矩形在那里正确显示。.lmao..我想我需要检查并再次减去另一个包是否显示计算器。- this.rectToDraw.height() / 2packageName- this.rectToDraw.height() / 2
0赞 cactustictacs 5/14/2021
你从哪里来?就像我说的,我对你正在使用的可访问性一无所知,但看起来你正在做的事情基本上是有效的,它只是发生了非常可疑的 50% 偏移量。在计算宽度/高度/x 和 y 偏移量时,是否考虑了填充?带有紫色按钮的图像看起来像是具有垂直填充或边距,但计算器按钮没有rectToDraw
0赞 Nikoloz Chitashvili 5/14/2021
我从它可以提供我的地方获取rectToDraw,并将包含我的对象。我明白你在说什么,也许紫色按钮有填充物和其他东西,但为什么 Google TalkBack 可以像在计算器中绘制一样绘制矩形?:/我认为 TalkBack 会有更多的 200 IQ,然后只是获取并绘制那个矩形。我仍然会仔细检查坐标计算。onAccessibilityEventevent.source.getBoundsInScreen(rectangle)rectangleRectgetBoundsInScreen

答:

2赞 Phil Weaver 5/15/2021 #1

神奇的是,TalkBack 不会画框。它实际上是在应用进程中绘制的。ViewRootImpl 中有代码可以处理它。此功能只能在启用触摸探索功能时使用,这使得它无法用于任何对与 TalkBack 非常相似的用户体验不感兴趣的用户。

期待后续,不,我们不打算开放它。叠加虽然偏移总是很繁琐,但是一种更具可扩展性的方法,可以帮助服务突出显示内容。

评论

0赞 Nikoloz Chitashvili 5/15/2021
所以,据我所知,我几乎不可能像 TalkBack 那样在视图周围绘制矩形,对吗?这太不幸了。然后我会尝试在我的案例中找到一些解决方案。
0赞 timr 1/3/2022
这可以用来在请求的 NodeInfo 上绘制绿色框吗?
1赞 Xlythe 4/27/2023 #2

我注意到,如果减去状态栏高度,对齐方式会有所改善

private void updateBounds(AccessibilityNodeInfo nodeInfo) {
  nodeInfo.getBoundsInScreen(mBoundsRect);
  mBoundsRect.top -= getStatusBarHeight();
  mBoundsRect.bottom -= getStatusBarHeight();
}

private int getStatusBarHeight() {
  WindowInsets insets = mWindowManager.getCurrentWindowMetrics().getWindowInsets();
  WindowInsetsCompat windowInsets = WindowInsetsCompat.toWindowInsetsCompat(insets);
  return windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()).top;
}

但我同样看到边界不一致,是否需要在应用程序和设备的屏幕尺寸上更改偏移量。

评论

0赞 Nikoloz Chitashvili 5/2/2023
嘿,很遗憾,我不再支持这个项目,但谢谢你的帮助!