- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用辅助功能服务在我的屏幕上获取 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/
我正在尝试实现一个AccessibilityService。我在下面分享了我的代码。当我从设置菜单打开无障碍服务时,onServiceConnected() 被调用,但 onAccessibiltyE
我在开发的应用程序中遇到了一个相当不幸的问题,该应用程序利用辅助功能服务在通知到达用户设备时对通知进行一些特殊处理。问题是,它工作得很好,但是永远不会调用服务的“onAccessibilityEven
在我的应用程序中,我必须捕获新的传入电子邮件消息通知并在屏幕上播放描述该事件的视频。我正在使用 onAccessibilityEvent(AccessibilityEvent event) 来收听生成
我正在使用 AccessibilityService 来确定在 Android 设备上运行的任何当前应用程序的 View 的文本和坐标。在每个事件 onAccessibilityEvent(...)
我是一名优秀的程序员,十分优秀!