如何检测系统对话框中的所有视图和文本?

时间:2016-02-23 15:35:24

标签: android text-to-speech accessibilityservice

我们说我有类似的情况:

Example

当这个对话框出现时,我正在使用辅助功能服务以便我的TTS引擎说话,但我唯一能够检测到的是可选择的视图(箭头指向的视图)。 有没有办法在对话框中检测标题和(更重要的是)整个文本?

1 个答案:

答案 0 :(得分:6)

是。我认为您可能会从可访问性事件中抓取这些项目,这些事件专注于单个节点。您要做的是查看整个视图层次结构。你可以用两种方法之一做到这一点。首先要注意的是,辅助功能节点是一棵树。就像heirarchy是一棵树一样。事实上,这个树与视图层次结构匹配,几乎是1到1.开发人员可以强制元素不包含在视图层次结构中,尽管在实践中并不经常这样做。即使他们这样做,你也可以得到这些信息。让我们假设我们想要这些信息。我们要做的第一件事就是确保它包含在内。

protected void onServiceConnected() {
    super.onServiceConnected();

    AccessibilityServiceInfo tempInfo = getServiceInfo();
    tempInfo.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
    setServiceInfo(tempInfo);

}

很有可能你可以跳过这一步,但为了以防万一!

在此之后它非常简单。首先,为了让您可以看到这些信息的位置,让我们编写一个可爱的小记录功能。

public static void logNodeHeirarchy(AccessibilityNodeInfo nodeInfo, int depth) {

    if (nodeInfo == null) return;

    String logString = "";

    for (int i = 0; i < depth; ++i) {
        logString += " ";
    }

    logString += "Text: " + nodeInfo.getText() + " " + " Content-Description: " + nodeInfo.getContentDescription();

    Log.v(LOG_TAG, logString);

    for (int i = 0; i < nodeInfo.getChildCount(); ++i) {
        logNodeHeirarchy(nodeInfo.getChild(i), depth + 1);
    }
}

此函数应记录辅助功能节点的整个树。将其作为静态功能添加到您的辅助功能服务中。现在我们只需要在根节点上调用它。您可以轻松更改记录的属性。我发现文本,内容描述和视图ID最有用。

@Override
public void onAccessibilityEvent(AccessibilityEvent e) {

    switch (e.getEventType()) {
        case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: {
            logNodeHeirarchy(getRootInActiveWindow(), 0);
        }
    }
}

这可以让您查看信息的位置。您所要做的就是弄清楚如何解析它。注意:您还可以使用getParent()从叶节点爬网。