android developer android developer - 4 months ago 24
Android Question

Is it possible to use adb commands to click on a view by finding its ID?

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

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

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

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.

EDIT: 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 :

enter image description here

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

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...


OK, given what "pskink" shown me, here's how to achieve this:

1.First, run the command :

"adb shell dumpsys activity top" 

2.Then, parse it as such :

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 (!line.contains("..."))
                    int newLineStart = getStartOfViewDetailsInLine(line);
                    if (newLineStart < currentLineStart) {
                        final Rect boundingBoxFromLine = getBoundingBoxFromLine(line);
                        result.left += boundingBoxFromLine.left;
                        result.right += boundingBoxFromLine.left;
                        result.bottom +=;
                        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 startIndex = line.lastIndexOf("... ") + 4;
        int endIndex = line.indexOf(',', startIndex);
        int left = Integer.parseInt(line.substring(startIndex, endIndex));
        startIndex = endIndex + 1;
        endIndex = line.indexOf('-', startIndex);
        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);

EDIT: the coordinates are not absolute , so more code is needed, to parse the parents' coordinates too.

EDIT: fixed.