Is there a way to get current activity's layout and views via adb?
Asked Answered
W

8

47

For environment reasons I can only use adb commands.

Is there a way to get the current layout attributes like id, position, text etc ?

Similar to what uiautomatorviewer shows.

Wimble answered 27/10, 2014 at 11:35 Comment(0)
P
83

Use adb shell uiautomator dump command:

Usage: uiautomator <subcommand> [options]

Available subcommands:

help: displays help message

runtest: executes UI automation tests
    runtest <class spec> [options]
    <class spec>: <JARS> < -c <CLASSES> | -e class <CLASSES> >
      <JARS>: a list of jar files containing test classes and dependencies. If
        the path is relative, it's assumed to be under /data/local/tmp. Use
        absolute path if the file is elsewhere. Multiple files can be
        specified, separated by space.
      <CLASSES>: a list of test class names to run, separated by comma. To
        a single method, use TestClass#testMethod format. The -e or -c option
        may be repeated. This option is not required and if not provided then
        all the tests in provided jars will be run automatically.
    options:
      --nohup: trap SIG_HUP, so test won't terminate even if parent process
               is terminated, e.g. USB is disconnected.
      -e debug [true|false]: wait for debugger to connect before starting.
      -e runner [CLASS]: use specified test runner class instead. If
        unspecified, framework default runner will be used.
      -e <NAME> <VALUE>: other name-value pairs to be passed to test classes.
        May be repeated.
      -e outputFormat simple | -s: enabled less verbose JUnit style output.

dump: creates an XML dump of current UI hierarchy
    dump [--verbose][file]
      [--compressed]: dumps compressed layout information.
      [file]: the location where the dumped XML should be stored, default is
      /storage/emulated/legacy/window_dump.xml

events: prints out accessibility events until terminated

By default it dumps the views hierarchy to $EXTERNAL_STORAGE/window_dump.xml

adb shell uiautomator dump
UI hierchary dumped to: /sdcard/window_dump.xml

Usually you would want to pull that file to your PC for further processing which would be an extra step. But there is a neat trick which allows to combine dumping and pulling into a single command. Using /dev/tty as a dump destination would make a single command which would print the whole dump to the stdout:

adb exec-out uiautomator dump /dev/tty
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><hierarchy rotation="0"><node ...></node></hierarchy>UI hierchary dumped to: /dev/tty
Patisserie answered 27/10, 2014 at 14:11 Comment(3)
Wanted to add a note that only one UIAutomator client can be running or the command will output "killed" and not work. I was stumped by this until I found out I was blocked by running tests using an open UIAutomator connection.Stevenson
@Alex I tried running the command ui automator dump to get the ui hierarchy from android emulator, but it seems that I am not getting the complete dump. What am I doing wrong? I am trying to get the dump for the activity of UCBrowser running in android emulator so that I can get the bound of a button/item to click. I have also asked a question on SO regarding same here - #43780990Prod
I got this error :( null root node returned by UiTestAutomationBridgeEstellaestelle
S
8

AndroidViewClient/culebra's dump tool lets you do precisely that. AndroidViewClient can be used as a library and also provides some tools like dump and culebra.

usage: dump [OPTION]... [serialno]

Options:
  -H, --help                       prints this help                             
  -V, --verbose                    verbose comments                             
  -v, --version
  -I, --ignore-secure-device       ignore secure device                         
  -E, --ignore-version-check       ignores ADB version check                    
  -F, --force-view-server-use      force view server use (even if UiAutomator present:w)
  -S, --do-not-start-view-server   don't start ViewServer                       
  -k, --do-not-ignore-uiautomator-killed don't ignore UiAutomator killed              
  -w, --window=WINDOW              dump WINDOW content (default: -1, all windows)
  -a, --all                        dump all information about Views             
  -i, --uniqueId                   dump View unique IDs                         
  -x, --position                   dump View positions                          
  -b, --bounds                     dump View bounds                             
  -d, --content-description        dump View content descriptions               
  -g, --tag                        dump View tags                               
  -c, --center                     dump View centers                            
  -f, --save-screenshot=FILE       save screenshot to file                      
  -W, --save-view-screenshots=DIR  save View screenshots to files in directory  
  -D, --do-not-dump-views          don't dump views, only useful if you specified -f or -W
  -A, --device-art=MODEL           device art model to frame screenshot (auto: autodetected)
  -Z, --drop-shadow                drop shadow for device art screenshot        
  -B, --glare                      screen glare over screenshot                 
  -h, --use-uiautomator-helper     use UiAutomatorHelper Android app            
  -X, --debug=LIST                 debug options 

       

running dump with no options, just prints the tree of Views and some of its basic properties, like ID

android.widget.FrameLayout  
   com.android.launcher3.Workspace com.google.android.apps.nexuslauncher:id/workspace 
      android.widget.FrameLayout com.google.android.apps.nexuslauncher:id/workspace_blocked_row 
         android.widget.TextView com.google.android.apps.nexuslauncher:id/date_text1 May 1
         android.widget.TextView com.google.android.apps.nexuslauncher:id/date_text2 MONDAY, 2017
      android.widget.TextView  Maps
   android.widget.ImageView com.google.android.apps.nexuslauncher:id/g_icon 
   android.widget.ImageView com.google.android.apps.nexuslauncher:id/all_apps_handle 
   android.view.ViewGroup com.google.android.apps.nexuslauncher:id/layout 
      android.widget.TextView  Messenger
      android.widget.TextView  Chrome

on the other hand, if you want the positions of the views, you can run

$ dump -x

android.widget.FrameLayout   (0, 0, 1440, 2392)
   com.android.launcher3.Workspace com.google.android.apps.nexuslauncher:id/workspace  (0, 0, 1440, 2392)
      android.widget.FrameLayout com.google.android.apps.nexuslauncher:id/workspace_blocked_row  (30, 126, 1380, 372)
         android.widget.TextView com.google.android.apps.nexuslauncher:id/date_text1 May 1 (1037, 194, 337, 162)
         android.widget.TextView com.google.android.apps.nexuslauncher:id/date_text2 MONDAY, 2017 (1092, 356, 282, 73)
      android.widget.TextView  Maps (30, 1614, 276, 372)
   android.widget.ImageView com.google.android.apps.nexuslauncher:id/g_icon  (30, 214, 276, 196)
   android.widget.ImageView com.google.android.apps.nexuslauncher:id/all_apps_handle  (636, 1986, 168, 98)
   android.view.ViewGroup com.google.android.apps.nexuslauncher:id/layout  (0, 2084, 1440, 308)
      android.widget.TextView  Messenger (306, 2112, 276, 280)
      android.widget.TextView  Chrome (858, 2112, 276, 280)

The options will give you control over the output. You can get some more info here.

update 2022

A newer backend is available for AndroidViewClient/culebra and one of the newer features is that you can also obtain the View hierarchy dump in JSON instead of XML.

For example:

$ dump -ah emulator-5554 | jq
⚠️ CulebraTester2 server should have been started and port redirected.
{
  "id": "hierarchy",
  "text": "Window Hierarchy",
  "timestamp": "2020-10-12T02:18:45.639Z",
  "children": [
    {
      "id": 0,
      "parent": -1,
      "text": "",
      "package": "com.android.systemui",
      "checkable": false,
      "clickable": false,
      "index": 0,
      "content_description": "",
      "focusable": false,
    ...

more details at CulebraTester2-public.

Statuesque answered 1/5, 2017 at 16:30 Comment(0)
A
6
adb pull $(adb shell uiautomator dump | grep -oP '[^ ]+.xml') /tmp/view.xml

Open /tmp/view.xml in a web browser like:

google-chrome /tmp/view.xml

adb exec-out uiautomator dump /dev/tty

from the other answer didn't work for me.

Aldosterone answered 7/10, 2016 at 18:33 Comment(1)
in my computer not work. i change to this adb pull $(adb shell uiautomator dump | egrep -o '/.*?xml')Helping
E
5

Use the following to view the xml layout in notepad or your default text editor

adb shell uiautomator dump && adb pull /sdcard/window_dump.xml && start window_dump.xml
Enallage answered 18/10, 2018 at 10:36 Comment(1)
how could i specifiy a specific file path to save it toFixed
I
4

I used the following on a Mac to print formatted xml to the console:

adb shell uiautomator dump && adb pull /sdcard/window_dump.xml $TMPDIR && more $TMPDIR/window_dump.xml | xmllint --format -

You may need to change the path of the /sdcard/window_dump.xml file to pull based on where the xml file is dumped.

Immediacy answered 3/4, 2017 at 7:0 Comment(1)
does it work even within the OS itself, using root ? Also, is there a way to just print it, instead of using a file?Waldemar
S
2

It is possible to control the resource with calculated position using by UIAutomator.

  • How to get the information about current layout information. adb exec-out "uiautomator dump /dev/tty > /dev/null

  • How to calculate the XY coordinates From the output acquired on above. We can find the bounds information of target control with resource-id. the bounds information is bounds="[334,1789][505,1960]" if the resource-id is "com.samsung.android.dialer:id/dialButton".

    <node index="0" text="" resource-id="com.samsung.android.dialer
:id/dialButton" class="android.widget.FrameLayout" package="com.samsung.android.dialer" content-desc="Call button" check
able="false" checked="false" clickable="true" enabled="true" focusable="true" focused="false" scrollable="false" long-cl
ickable="true" password="false" selected="false" bounds="[334,1789][505,1960]">
  • bounds value in the node Top-Left : [334,1789], Bottom-Right : [505, 1960]

we can get the center position of control("com.samsung.android.dialer :id/dialButton") from the bounds values.

X = 334 + round{(505-334 + 1) / 2} => 420 Y = 1789 + round{(1960 – 1789 + 1) / 2} => 1875

We can check the bound of target control and it can be used for remote control of target resource.

adb shell input tap 420 1875

For more information, I hope following link is helpful for your question.

https://lowellahn.tistory.com/m/1

Stern answered 16/3, 2022 at 15:44 Comment(3)
First off welcome to Stack Overflow. What do you mean by resource and calculated position. Please provide more info than a URL (which may become broken at any time.Helicopter
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Heavyhanded
this worked for me. However switching to a different android device , the formula does not work. Does not make sense that a different android phone (with different ratio) providing the xml dump with the bounds, the calculation is offFixed
I
1

adb shell uiautomator dump /dev/stdout works better for me than adb shell uiautomator dump /dev/tty.

Interfluent answered 8/9, 2021 at 18:53 Comment(1)
i cant find where the file is being saved. any information other than, in the sd card?Fixed
P
-7

In 2020 it's recommended to use a tool built-in Android Studio.

  1. Connect your phone
  2. Follow the screenshot

Source: https://developer.android.com/studio/debug/layout-inspector

enter image description here

Pedestrianize answered 8/1, 2020 at 12:16 Comment(1)
In 2020 it's recommended to read the question you are replying to. For environment reasons I can only use adb commands.Patisserie

© 2022 - 2024 — McMap. All rights reserved.