gpt4 book ai didi

Android onAccessibilityEvent获取TextView的X和Y位置

转载 作者:太空宇宙 更新时间:2023-11-03 11:54:37 26 4
gpt4 key购买 nike

我正在尝试使用辅助功能服务在我的屏幕上获取 TextView 的 X 和 Y 位置以查找 TextView,这可能吗?我发现的所有内容都需要您先触摸屏幕。以下是我获取节点信息的方式。

public class MyAccessibilityService extends AccessibilityService {

@TargetApi(16)
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityNodeInfo source = event.getSource();
}
}

最佳答案

您可以随时从无障碍服务中任意搜索无障碍 View 层次结构!不过,我确实建议在某种类型的可访问性事件的上下文中这样做,因为这样可以确保有要遍历的屏幕内容!在随机回调中这样做充其量是挑剔的。这是用于此类目的的合理的可访问性配置 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/accessibility_service_description"
android:accessibilityEventTypes="typeWindowContentChanged|typeWindowsChanged|typeWindowStateChanged"
android:accessibilityFlags="flagReportViewIds|flagIncludeNotImportantViews"
android:canRetrieveWindowContent="true"
android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="1000"
android:settingsActivity=".SettingsActivity"
/>

下面是对其中一些领域的一些评论。

android:notificationTimeout="1000"

每秒仅检索一次给定类型的辅助功能事件!列出事件后,任何较低的设置都会非常冗长。我们只依靠它来调用我们的回调并确保我们有节点。对于这些目的,每秒一次只是 DANDY。根据需要进行调整。

android:accessibilityEventTypes="typeWindowContentChanged|typeWindowsChanged|typeWindowStateChanged"

粗略地说,这是允许您捕获所有屏幕更改事件的事件子集。打开一个新窗口...扫描 View 层次结构!

android:accessibilityFlags="flagReportViewIds|flagIncludeNotImportantViews"

标记包括不重要的 View 将在 AccessibilityNodeInfo 层次结构中包含更多 View 。具体来说,许多布局 View 等 Android 操作系统通常认为出于可访问性目的不需要。我想包括这个,因为这也是一个开发人员可调整的属性,Android 开发人员在可访问性方面是出了名的不了解。最好只获取所有内容并自己整理!

好的,这就是您的服务配置!现在,剩下的就很容易了。您要做的是递归遍历子节点的根节点,直到找到 TextView 节点。我在下面设置了一个愚蠢的服务,它会在每次屏幕更新时找到第一个 TextView 节点(除非给定上面的服务配置 XML,它们每秒出现不止一次),然后记录它的屏幕坐标。

class MyAccessibilityService extends AccessibilityService {

@Override
public void onAccessibilityEvent(AccessibilityEvent e) {

//You can actually call getRootInActiveWindow() any time!
//Doing so here ensures that the screen is in a reasonable state
//and not in the middle of rendering or something else silly.
final AccessibilityNodeInfo textNodeInfo = findTextViewNode(getRootInActiveWindow());

if (textNodeInfo == null) return;

Rect rect = new Rect();

textNodeInfo.getBoundsInScreen(rect);

Log.i(A11yService.class.getSimpleName(), "The TextView Node: " + rect.toString());

}


public AccessibilityNodeInfo findTextViewNode(AccessibilityNodeInfo nodeInfo) {

//I highly recommend leaving this line in! You never know when the screen content will
//invalidate a node you're about to work on, or when a parents child will suddenly be gone!
//Not doing this safety check is very dangerous!
if (nodeInfo == null) return null;

Log.v(A11yService.class.getSimpleName(), nodeInfo.toString());

//Notice that we're searching for the TextView's simple name!
//This allows us to find AppCompat versions of TextView as well
//as 3rd party devs well names subclasses... though with perhaps
//a few poorly named unintended stragglers!
if (nodeInfo.getClassName().toString().contains(TextView.class.getSimpleName())) {
return nodeInfo;
}

//Do other work!

for (int i = 0; i < nodeInfo.getChildCount(); i++) {
AccessibilityNodeInfo result = findTextViewNode(nodeInfo.getChild(i));

if (result != null) return result;
}

return null;
}

//Required for a valid Accessibility Service.
@Override
public void onInterrupt() {}
}

您还可以找到我构建的开源库,名为 Accessibility Service Utilities ,这让所有这些东西变得更加容易! A11yNodeInfoMatcher 类就是您想要的。

关于Android onAccessibilityEvent获取TextView的X和Y位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45423728/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com