Rag*_*ghu 3 android accessibilityservice
我是安卓的初学者。我想获取用户当前正在查看的视图的视图 ID。我让我的问题更清楚一点。假设用户打开 MakeMyTrip 并导航到航班预订页面。现在我想获取该特定布局的视图 ID。下面是我的服务类和 xml 配置文件。
public class MyAccessibilityService extends AccessibilityService {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityNodeInfo source = event.getSource();
Log.d("ViewID",source.getViewIdResourceName());
}
@Override
public void onInterrupt() {
}
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeWindowContentChanged"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagReportViewIds"
android:canRetrieveWindowContent="true"
android:description="@string/accessibility_service_description"
android:packageNames="com.makemytrip" />
Run Code Online (Sandbox Code Playgroud)
我的猜测是你打电话给
Log.d("ViewID",source.getViewIdResourceName());
Run Code Online (Sandbox Code Playgroud)
是这样做的:
Log.d("ViewID", null)
Run Code Online (Sandbox Code Playgroud)
window_content_changed事件的源节点将是其内容更新的布局的根节点。这极不可能有 viewIDResourceName。大多数视图没有资源名称,可通过直接访问视图访问的视图 ID 只是自动生成的哈希值,没有任何意义。只有具有实际 viewResourceNames 的视图才会将其名称报告给无障碍服务。因此,如果元素没有R.id.viewResourceName可访问性服务将报告null该值。Android Log 实用程序无法记录空值,您至少必须给它一个空字符串。
你应该这样做。
String viewIdName = source.getViewIdResourceName();
Log.d("ViewID", (viewIdName != null) ? viewIdName : "NO VIEW ID");
Run Code Online (Sandbox Code Playgroud)
值得注意的是,对于打印出来的地方,您总是会得到“NO VIEW ID”。您将不得不向下爬取视图层次结构以找到具有资源名称的视图。找到一些按钮或您分配了 ID 的东西!或者潜在地侦听不同类型的可访问性事件。不过要小心!并非所有事件都有源节点!所以,如果你听
android:accessibilityEventTypes="typeAllMask"
Run Code Online (Sandbox Code Playgroud)
您还需要检查空源节点。或者你会得到不同类型的空指针异常。
编辑:用于记录整个可访问性节点视图层次结构的基本递归函数。
public static void logViewHierarchy(AccessibilityNodeInfo nodeInfo, final int depth) {
if (nodeInfo == null) return;
String spacerString = "";
for (int i = 0; i < depth; ++i) {
spacerString += '-';
}
//Log the info you care about here... I choce classname and view resource name, because they are simple, but interesting.
Log.d("TAG", spacerString + nodeInfo.getClassName() + " " + nodeInfo.getViewIdResourceName());
for (int i = 0; i < nodeInfo.getChildCount(); ++i) {
logViewHierarchy(nodeInfo.getChild(i), depth+1);
}
}
//Then call it like this from anywhere in your service, don't necessarily have to use the root node.
logViewHierarchy(getRootInActiveWindow(), 0);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6235 次 |
| 最近记录: |