下面列出了android.view.accessibility.AccessibilityNodeInfo#getBoundsInScreen ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void traverse_node_recursive(AccessibilityNodeInfo node, int level) {
if (node == null) {
return;
}
int child_cnt = node.getChildCount();
StringBuilder sb = new StringBuilder();
if (child_cnt > 0) {
for (int i = 0; i < child_cnt; i++) {
traverse_node_recursive(node.getChild(i), level + 1);
}
} else {
Rect bounds = new Rect();
node.getBoundsInScreen(bounds);
for (int i = 0; i < level; i++) {
sb.append(" ");
}
sb.append(node.getText());
sb.append(bounds.toShortString());
Util.log(sb);
}
}
/**
* Returns the node's bounds clipped to the size of the display
*
* @param node
* @param width pixel width of the display
* @param height pixel height of the display
* @return null if node is null, else a Rect containing visible bounds
*/
static Rect getVisibleBoundsInScreen(AccessibilityNodeInfo node, int width, int height) {
if (node == null) {
return null;
}
// targeted node's bounds
Rect nodeRect = new Rect();
node.getBoundsInScreen(nodeRect);
Rect displayRect = new Rect();
displayRect.top = 0;
displayRect.left = 0;
displayRect.right = width;
displayRect.bottom = height;
nodeRect.intersect(displayRect);
return nodeRect;
}
public static boolean compareAccessibilityNodeInfo(AccessibilityNodeInfo n1, AccessibilityNodeInfo n2) {
if (n1 != null && n2 != null) {
String c1 = n1.getClassName().toString();
String c2 = n2.getClassName().toString();
Rect b1 = new Rect();
Rect b2 = new Rect();
n1.getBoundsInScreen(b1);
n2.getBoundsInScreen(b2);
int a1 = b1.height() * b1.width();
b1.intersect(b2);
int a2 = b1.height() * b1.width();
return c1.equals(c2) && (a2 > ((int) (a1 * 0.95)));
} else {
return false;
}
}
/**
* Returns the node's bounds clipped to the size of the display
*
* @param node
* @param width pixel width of the display
* @param height pixel height of the display
* @return null if node is null, else a Rect containing visible bounds
*/
public static Rect getVisibleBoundsInScreen(AccessibilityNodeInfo node, int width, int height) {
if (node == null) {
return null;
}
// targeted node's bounds
Rect nodeRect = new Rect();
node.getBoundsInScreen(nodeRect);
Rect displayRect = new Rect();
displayRect.top = 0;
displayRect.left = 0;
displayRect.right = width;
displayRect.bottom = height;
nodeRect.intersect(displayRect);
return nodeRect;
}
/**
* Returns the node's bounds clipped to the size of the display
*
* @param width pixel width of the display
* @param height pixel height of the display
* @return (-1, -1, -1, -1) if node is null, else a Rect containing visible bounds
*/
private static Rect getVisibleBoundsInScreen(AccessibilityNodeInfo node, int width, int height) {
Rect nodeRect = new Rect(-1, -1, -1, -1);
if (node == null) {
return nodeRect;
}
// targeted node's bounds
node.getBoundsInScreen(nodeRect);
Rect displayRect = new Rect();
displayRect.top = 0;
displayRect.left = 0;
displayRect.right = width;
displayRect.bottom = height;
nodeRect.intersect(displayRect);
return nodeRect;
}
public void refresh(AccessibilityNodeInfo node) {
if (sealed) {
throw new IllegalArgumentException("sealed! " + super.toString());
}
mFocused = node.isFocused();
node.getBoundsInScreen(mBoundsInScreen);
node.getBoundsInParent(mBoundsInParent);
mBoundsInScreen.offset(0, -OverlayDecryptView.SCREEN_OFFSET_Y);
mText = AccessibilityNodeInfoUtils.getNodeText(node);
mTextString = mText == null ? null : mText.toString();
mIsEncoded = mText == null ? false : CryptoHandlerFacade.Companion.isEncoded(mCtx, mTextString);
if (mIsEncoded) {
mIsTextView = true;
}
mIsEditableTextNode = (node.isEditable()
&& node.isEnabled()
&& mIsEditText
&& !node.isPassword());
}
private static void dump(AccessibilityEvent event) {
AccessibilityNodeInfo source = event.getSource();
if (source == null) {
Util.err("event source: NULL");
return;
}
Rect bounds = new Rect();
source.getBoundsInScreen(bounds);
int cnt = -1;
if (source.getClassName().equals(ListView.class.getCanonicalName())) {
cnt = event.getItemCount();
int from = event.getFromIndex();
int to = event.getToIndex();
Util.log(event.getEventTime() + ": " + AccessibilityEvent.eventTypeToString(event.getEventType()) + "," + source.getClassName() + "," + cnt + ", [" + from + " --> " + to + "], "
+ bounds.toShortString());
} else {
Util.log(event.getEventTime() + ": " + AccessibilityEvent.eventTypeToString(event.getEventType()) + "," + source.getClassName() + "," + bounds.toShortString());
}
}
/**
* Returns the node's bounds clipped to the size of the display
*
* @param width pixel width of the display
* @param height pixel height of the display
* @return null if node is null, else a Rect containing visible bounds
*/
static Rect getVisibleBoundsInScreen(AccessibilityNodeInfo node, int width, int height) {
if (node == null) {
return null;
}
// targeted node's bounds
Rect nodeRect = new Rect();
node.getBoundsInScreen(nodeRect);
Rect displayRect = new Rect();
displayRect.top = 0;
displayRect.left = 0;
displayRect.right = width;
displayRect.bottom = height;
nodeRect.intersect(displayRect);
return nodeRect;
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private synchronized static ViewItem nodeInfoToViewItem(@Nullable AccessibilityNodeInfo node, int depth) {
ViewItem viewItem = new ViewItem();
viewItem.id = id++;
viewItem.level = depth;
ViewItem topLevelNode = getLastTopLevelNode(itemList, depth - 1);
viewItem.parentId = (topLevelNode == null ? NO_PARENT : topLevelNode.id);
if (node == null) {
return viewItem;
}
Rect rect = new Rect();
node.getBoundsInScreen(rect);
viewItem.bounds = new Point(rect.left, rect.top);
viewItem.wh = new Point(rect.width(), rect.height());
viewItem.simpleClassName = node.getClassName().toString();
if (viewItem.simpleClassName.contains(".")) {
viewItem.simpleClassName = viewItem.simpleClassName.substring(viewItem.simpleClassName.lastIndexOf("."));
}
return viewItem;
}
private static void logNodeHierachy(AccessibilityNodeInfo nodeInfo, int depth) {
Rect bounds = new Rect();
nodeInfo.getBoundsInScreen(bounds);
StringBuilder sb = new StringBuilder();
if (depth > 0) {
for (int i=0; i<depth; i++) {
sb.append(" ");
}
sb.append("\u2514 ");
}
sb.append(nodeInfo.getClassName());
sb.append(" (" + nodeInfo.getChildCount() + ")");
sb.append(" " + bounds.toString());
if (nodeInfo.getText() != null) {
sb.append(" - \"" + nodeInfo.getText() + "\"");
}
Log.v(TAG, sb.toString());
for (int i=0; i<nodeInfo.getChildCount(); i++) {
AccessibilityNodeInfo childNode = nodeInfo.getChild(i);
if (childNode != null) {
logNodeHierachy(childNode, depth + 1);
}
}
}
private static AccessibilityNodeInfo findSmallestNodeAtPoint(AccessibilityNodeInfo sourceNode, int x, int y) {
Rect bounds = new Rect();
sourceNode.getBoundsInScreen(bounds);
if (!bounds.contains(x, y)) {
return null;
}
for (int i=0; i<sourceNode.getChildCount(); i++) {
AccessibilityNodeInfo nearestSmaller = findSmallestNodeAtPoint(sourceNode.getChild(i), x, y);
if (nearestSmaller != null) {
return nearestSmaller;
}
}
return sourceNode;
}
/**
* Returns the view's <code>bounds</code> property. See {@link #getVisibleBounds()}
*
* @return Rect
* @throws UiObjectNotFoundException
* @since API Level 16
*/
public Rect getBounds() throws UiObjectNotFoundException {
Tracer.trace();
AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
if(node == null) {
throw new UiObjectNotFoundException(mUiSelector.toString());
}
Rect nodeRect = new Rect();
node.getBoundsInScreen(nodeRect);
return nodeRect;
}
private void compute_feature_vector(Hashtable<String, FeatureValuePair> map, AccessibilityNodeInfo node, int level) {
int child_cnt = node.getChildCount();
if (child_cnt > 0) {
for (int i = 0; i < child_cnt; i++) {
AccessibilityNodeInfo child = node.getChild(i);
compute_feature_vector(map, child, level + 1);
}
} else {
String key = node.getClassName().toString() + "@" + level;
FeatureValuePair value;
int size = 0;
CharSequence text = node.getText();
if (text != null) {
size = text.toString().length();
}
if (node.getClassName().toString().equals(ImageView.class.getCanonicalName())) {
Rect bounds = new Rect();
node.getBoundsInScreen(bounds);
String timestamp = new SimpleDateFormat("MM-dd'T'HH-mm-ss-SSS").format(new Date());
size = get_imageview_size("/data/local/tmp/local/tmp/haos.png", bounds, "/data/local/tmp/local/tmp/" + key + "_" + timestamp + ".png");
} else {
// Util.log(node.getClassName() + " NOT " + ImageView.class.getCanonicalName());
}
value = map.containsKey(key) ? map.get(key) : new FeatureValuePair(0, 0);
value.count++;
value.size += size;
map.put(key, value);
// Util.log("Leaf: " + key + ", " + size);
}
}
/**
* Returns the view's <code>bounds</code> property. See {@link #getVisibleBounds()}
*
* @return Rect
* @throws UiObjectNotFoundException
* @since API Level 16
*/
public Rect getBounds() throws UiObjectNotFoundException {
Tracer.trace();
AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
if(node == null) {
throw new UiObjectNotFoundException(mUiSelector.toString());
}
Rect nodeRect = new Rect();
node.getBoundsInScreen(nodeRect);
return nodeRect;
}
/** Returns the visible bounds of {@code node} in screen coordinates. */
private Rect getVisibleBounds(AccessibilityNodeInfo node) {
// Get the object bounds in screen coordinates
Rect ret = new Rect();
node.getBoundsInScreen(ret);
// Trim any portion of the bounds that are not on the screen
Rect screen = new Rect(0, 0, mDevice.getDisplayWidth(),
mDevice.getDisplayHeight());
ret.intersect(screen);
// Find the visible bounds of our first scrollable ancestor
AccessibilityNodeInfo ancestor = null;
for (ancestor = node.getParent(); ancestor != null; ancestor = ancestor
.getParent()) {
// If this ancestor is scrollable
if (ancestor.isScrollable()) {
// Trim any portion of the bounds that are hidden by the
// non-visible portion of our
// ancestor
Rect ancestorRect = getVisibleBounds(ancestor);
ret.intersect(ancestorRect);
break;
}
}
return ret;
}
private AccessibilityNodeInfo createNodeForHost(int rootId) {
// Since we don't want the parent to be focusable, but we can't remove
// actions from a node, copy over the necessary fields.
final AccessibilityNodeInfo result = AccessibilityNodeInfo.obtain(mView);
final AccessibilityNodeInfo source = AccessibilityNodeInfo.obtain(mView);
mView.onInitializeAccessibilityNodeInfo(source);
// Copy over parent and screen bounds.
Rect rect = new Rect();
source.getBoundsInParent(rect);
result.setBoundsInParent(rect);
source.getBoundsInScreen(rect);
result.setBoundsInScreen(rect);
// Set up the parent view, if applicable.
final ViewParent parent = mView.getParentForAccessibility();
if (parent instanceof View) {
result.setParent((View) parent);
}
// Populate the minimum required fields.
result.setVisibleToUser(source.isVisibleToUser());
result.setEnabled(source.isEnabled());
result.setPackageName(source.getPackageName());
result.setClassName(source.getClassName());
// Add the Chrome root node.
if (isFrameInfoInitialized()) {
result.addChild(mView, rootId);
}
return result;
}
/**
*
* @param nodeInfo
* @return
*/
public static boolean isIncomingMessage(AccessibilityNodeInfo nodeInfo, Context context) {
Rect rect = new Rect();
nodeInfo.getBoundsInScreen(rect);
return rect.left < UIUtils.getScreenHeight(context)
- rect.right && nodeInfo.getText() != null;
}
public static SerializedAccessibilityNodeInfo serialize(AccessibilityNodeInfo node){
SerializedAccessibilityNodeInfo serializedNode = new SerializedAccessibilityNodeInfo();
Rect boundsInScreen = new Rect(), boundsInParent = new Rect();
if(node == null){
return null;
}
if(node.getClassName() != null)
serializedNode.className = node.getClassName().toString();
node.getBoundsInScreen(boundsInScreen);
node.getBoundsInParent(boundsInParent);
serializedNode.boundsInScreen = boundsInScreen.flattenToString();
serializedNode.boundsInParent = boundsInParent.flattenToString();
if(node.getContentDescription() != null)
serializedNode.contentDescription = node.getContentDescription().toString();
if(node.getText() != null){
serializedNode.text = node.getText().toString();
}
if(node.getViewIdResourceName() != null)
serializedNode.viewId = node.getViewIdResourceName();
int childCount = node.getChildCount();
for(int i = 0; i < childCount; i ++){
if(node.getChild(i) != null){
serializedNode.children.add(serialize(node.getChild(i)));
}
}
return serializedNode;
}
Builder(int id, @Nullable ViewHierarchyElementAndroid parent, AccessibilityNodeInfo fromInfo) {
// Bookkeeping
this.id = id;
this.parentId = (parent != null) ? parent.getId() : null;
// API 18+ properties
this.resourceName = AT_18 ? fromInfo.getViewIdResourceName() : null;
this.editable = AT_18 ? fromInfo.isEditable() : null;
// API 16+ properties
this.visibleToUser = AT_16 ? fromInfo.isVisibleToUser() : null;
// API 21+ properties
if (AT_21) {
ImmutableList.Builder<ViewHierarchyActionAndroid> actionBuilder =
new ImmutableList.Builder<>();
actionBuilder.addAll(
Lists.transform(
fromInfo.getActionList(),
action -> ViewHierarchyActionAndroid.newBuilder(action).build()));
this.actionList = actionBuilder.build();
}
// API 24+ properties
this.drawingOrder = AT_24 ? fromInfo.getDrawingOrder() : null;
// API 29+ properties
this.hasTouchDelegate = AT_29 ? (fromInfo.getTouchDelegateInfo() != null) : null;
// Base properties
this.className = fromInfo.getClassName();
this.packageName = fromInfo.getPackageName();
this.accessibilityClassName = fromInfo.getClassName();
this.contentDescription = SpannableStringAndroid.valueOf(fromInfo.getContentDescription());
this.text = SpannableStringAndroid.valueOf(fromInfo.getText());
this.importantForAccessibility = true;
this.clickable = fromInfo.isClickable();
this.longClickable = fromInfo.isLongClickable();
this.focusable = fromInfo.isFocusable();
this.scrollable = fromInfo.isScrollable();
this.canScrollForward =
((fromInfo.getActions() & AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) != 0);
this.canScrollBackward =
((fromInfo.getActions() & AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) != 0);
this.checkable = fromInfo.isCheckable();
this.checked = fromInfo.isChecked();
this.touchDelegateBounds = new ArrayList<>(); // Populated after construction
android.graphics.Rect tempRect = new android.graphics.Rect();
fromInfo.getBoundsInScreen(tempRect);
this.boundsInScreen = new Rect(tempRect.left, tempRect.top, tempRect.right, tempRect.bottom);
this.nonclippedHeight = null;
this.nonclippedWidth = null;
this.textSize = null;
this.textColor = null;
this.backgroundDrawableColor = null;
this.typefaceStyle = null;
this.enabled = fromInfo.isEnabled();
}
private Rect getBounds(AccessibilityNodeInfo node) {
Rect rect = new Rect();
node.getBoundsInScreen(rect);
return rect;
}