是否可以使用adb命令通过查找视图ID来单击视图? [英] Is it possible to use adb commands to click on a view by finding its ID?

查看:404
本文介绍了是否可以使用adb命令通过查找视图ID来单击视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个应用程序(无论是由我还是不是由调试/发布构建),都有一个特定视图的ID。

Suppose I have an app (in debug/release build , made by me or not), which has an ID for a specific view.

是否可以调用adb命令以单击该视图吗?

Is it possible to call adb command to click on this view?

我知道可以单击特定的坐标,但是可以使用ID代替吗?

I know it's possible to make it click on a specific coordinate, but is it possible to use the ID instead ?

我之所以这样问,是因为我确实知道布局检查器工具(可通过Android Studio获得)和视图层次结构工具(可通过 Android设备监视器获得) ,以前通过DDMS使用)可以显示视图的ID(甚至包括其坐标和边界框),因此也许是执行一些自动测试时模拟触摸的更好方法。

I ask this because I do know that the "Layout Inspector" tool (available via Android Studio) and the "View hierarchy" tool (available via "Android Device Monitor", previously used via DDMS) can show the ids of the views (and even their coordinates and bounding box), so maybe it can be a better way to simulate touches when performing some automatic tests.

如果需要,我可以使用植根方法。

I can use a rooted method if needed.

编辑:我设置了赏金以防万一有一种比我自己的答案中写的方法更简单/更好的方法,那就是解析 adb shell dumpsys activity top的结果。

I've set a bounty in case there is an easier/better way than what I've written in my own answer, which was to parse the result of "adb shell dumpsys activity top" .

我想知道是否有可能获取屏幕上显示的视图坐标(当然还有尺寸),包括尽可能多的信息(以识别每)。
这也应该可以通过设备实现。可能具有与监控工具中可用输出数据相同的输出数据:

I would like to know if it's possible to get the views coordinates (and sizes of course) that are shown on the screen, including as much information about them (to identify each). This should be possible via the device too. Maybe something that has the same output data of what's available from the "monitor" tool :

注意如何获取视图的基本信息,包括文本,ID和每个视图的边界。

Notice how it can get the basic information of the views, including the text, the id, and the bounds of each.

如我所读,这可以通过AccessibilityService来实现,但遗憾的是,我无法理解其全部工作原理,功能,触发方式,它的要求是什么,等等...

As I've read, this might be possible via AccessibilityService, but sadly I can't understand how it all works, what are its capabilities, how to trigger it, what are its requirements, etc...

推荐答案

使用 @ pskink 在上面的评论中进行了解释,这是我实现此目标的方法:

Using what @pskink explained in the comments above, here's how I achieved this:

首先,我运行了以下命令:

First, I ran this command:

adb shell dumpsys activity top

然后,我使用以下代码对其进行解析:

Then, I used this code to parse it:

public class ViewCoordsGetter {
    public static Rect getViewBoundyingBox(String viewIdStr) {
        final List<String> viewHierarchyLog = //result of the command
        for (int i = 0; i < viewHierarchyLog.size(); ++i) {
            String line = viewHierarchyLog.get(i);
            if (line.contains(":id/" + viewIdStr + "}")) {
                Rect result = getBoundingBoxFromLine(line);
                if (i == 0)
                    return result;
                int currentLineStart = getStartOfViewDetailsInLine(line);
                for (int j = i - 1; j >= 0; --j) {
                    line = viewHierarchyLog.get(j);
                    if ("View Hierarchy:".equals(line.trim()))
                        break;
                    int newLineStart = getStartOfViewDetailsInLine(line);
                    if (newLineStart < currentLineStart) {
                        final Rect boundingBoxFromLine = getBoundingBoxFromLine(line);
                        result.left += boundingBoxFromLine.left;
                        result.right += boundingBoxFromLine.left;
                        result.top += boundingBoxFromLine.top;
                        result.bottom += boundingBoxFromLine.top;
                        currentLineStart = newLineStart;
                    }
                }
                return result;
            }
        }
        return null;
    }

    private static int getStartOfViewDetailsInLine(String s) {
        int i = 0;
        while (true)
            if (s.charAt(i++) != ' ')
                return --i;
    }

    private static Rect getBoundingBoxFromLine(String line) {
        int endIndex = line.indexOf(',', 0);
        int startIndex = endIndex - 1;
        while (!Character.isSpaceChar(line.charAt(startIndex - 1)))
            --startIndex;
        int left = Integer.parseInt(line.substring(startIndex, endIndex));
        startIndex = endIndex + 1;
        endIndex = line.indexOf('-', startIndex);
        endIndex = line.charAt(endIndex - 1) == ',' ? line.indexOf('-', endIndex + 1) : endIndex;
        int top = Integer.parseInt(line.substring(startIndex, endIndex));
        startIndex = endIndex + 1;
        endIndex = line.indexOf(',', startIndex);
        int right = Integer.parseInt(line.substring(startIndex, endIndex));
        startIndex = endIndex + 1;
        //noinspection StatementWithEmptyBody
        for (endIndex = startIndex + 1; Character.isDigit(line.charAt(endIndex)); ++endIndex)
            ;
        int bot = Integer.parseInt(line.substring(startIndex, endIndex));
        return new Rect(left, top, right, bot);
    }
}

这篇关于是否可以使用adb命令通过查找视图ID来单击视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆