问题
Let's say I have a similar scenario:
I'm using an accessibility service in order to my TTS engine talk when this dialog appears, but the only thing I was able to detect were the selectable views (those pointed by the arrow). Is there any way to detect the title and (more importantly) whole text inside the dialog?
回答1:
Yes. I think it is likely that you're grabbing these items off of accessibility events, which focus on a single node. What you want to do instead is look at the entire view hierarchy. You can do this one of two ways. First thing to note is that Accessibility Nodes are a tree. Just like the view heirarchy is a tree. In fact, this tree matches the view hierarchy, almost 1 to 1. Developers can force an element to not be included in the view hierarchy, though this isn't done often in practice. Even if they do you can get this information regardless. Let's assume we want this information. First thing we want to do is make sure it's included.
protected void onServiceConnected() {
super.onServiceConnected();
AccessibilityServiceInfo tempInfo = getServiceInfo();
tempInfo.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
setServiceInfo(tempInfo);
}
It's highly likely you can skip this step, but just in case!
After this it's quite simple. First, so that you can see where this information is, let's write a cute little logging function.
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);
}
}
This function should log the entire tree of an accessibility node. Add it as a static function to your accessibility service. Now we just need to call it on the root node. You can easily change the properties that get logged. I find text, content description, and view id to be the most useful.
@Override
public void onAccessibilityEvent(AccessibilityEvent e) {
switch (e.getEventType()) {
case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: {
logNodeHeirarchy(getRootInActiveWindow(), 0);
}
}
}
This should allow you to see where the information is. All you have to do is figure out how to parse it. Note: You can also crawl up from a leaf node, using getParent().
来源:https://stackoverflow.com/questions/35581688/how-to-detect-all-views-and-text-inside-a-system-dialog