我需要使用第 3 方应用程序的资源 ID(我知道)来读取该资源。 我引用的是这个链接: How to read window content (using accessibilityService) and evoking UI using draw over other app permission in Android?为了实现这个功能。
问题:使用 event.getSource() 创建的 AccessibilityNodeInfo 对象源为 null。
鉴于我知道 Source 类,我想创建 AccessibilityNodeInfo 的对象。
最佳答案
并非所有事件都与“源”节点关联。事实上,大多数 super 频繁发生的事件并非如此。 (触摸交互、窗口更改等)。您需要确保按具有源节点的事件进行过滤。话虽如此,我怀疑这是否是您想要的,具有源节点的事件很少会包含您正在寻找的节点。在响应辅助功能事件的某些子集之后,您可能希望从根节点开始探索 AccessibilityNodeInfo 层次结构。
首先,确保您的服务配置正确。我认为看起来像这样的 service_config.xml 就足够了。
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/accessibility_service_description"
android:accessibilityEventTypes="typeWindowsChanged|typeWindowContentChanged|typeViewScrolled"
android:accessibilityFlags="flagReportViewIds"
android:canRetrieveWindowContent="true"
android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="1000"
android:settingsActivity="com.moba11y.basicaccessibilityservice.SettingsActivity"
/>
其中的一些亮点:
android:accessibilityEventTypes="typeWindowsChanged|typeWindowContentChanged|typeViewScrolled"
此行旨在捕获在窗口上绘制任何新内容的事件类型。注意:这些事件都没有自己的 event.getSource() 节点。每次都会为空! (恕我直言:这些事件的 event.getSource() 应该是根节点,但这只是我的问题,请询问 Google!)。
android:notificationTimeout="1000"
每秒仅获取每种特定类型的事件一次。非常适合限制频繁引发的事件,例如滚动事件。
android:canRetrieveWindowContent="true"
当我调用 getRootInActiveWindow()
时不要抛出异常。
android:accessibilityFlags="flagReportViewIds"
确保使用 AccessibilityNodeInfo 报告 viewID。
有了正确的辅助服务配置,剩下的就非常简单了。在辅助功能事件的子集之后(上面的配置旨在捕获新的屏幕内容),在 View 层次结构中搜索您的 View ID。
public static void exploreNodeHierarchy(final AccessibilityNodeInfo nodeInfo, final int depth) {
//Super important check! AccessibilityNodes can get invalidated at ANY time.
if (nodeInfo == null) return;
//Log the nodeINfo to string, with some tabs for visible parent/child relationships.
Log.d(BasicAccessibilityService.class.getName(), new String(new char[depth]).replace("\0", "\t") + nodeInfo.toString());
if (nodeInfo.getViewIdResourceName() == "the view id you have") {
//Do work here.
}
for (int i = 0; i < nodeInfo.getChildCount(); ++i) {
logNodeHierarchy(nodeInfo.getChild(i), depth + 1);
}
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
exploreNodeHierarchy(getRootInActiveWindow(), 0);
}
关于java - event.getSource 在辅助功能服务中返回 null。 (捕获第 3 方应用程序的源),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45620584/