Using ADB to access a particular UI control on the screen
Yes you can, although it's not pretty.
You can get the view hierarchy by using this command:
adb exec-out uiautomator dump /dev/tty
, which prints the output to the screen as an XML file. Unfortunately it's not valid XML, as there's some text appended. So let's filter that out:
adb exec-out uiautomator dump /dev/tty | awk '{gsub("UI hierchary dumped to: /dev/tty", "");print}'
Now we've got a valid XML. Let's run this through XPath:
adb exec-out uiautomator dump /dev/tty | awk '{gsub("UI hierchary dumped to: /dev/tty", "");print}' | xpath '//node[@resource-id="com.example:id/btnDone"]' 2> /dev/null
, which will search for all nodes with the specific ID. Now you got the node, and you can do some more stuff on this.
If you were to get only the viewbounds, you'd have to do this:
adb exec-out uiautomator dump /dev/tty | awk '{gsub("UI hierchary dumped to: /dev/tty", "");print}' | xpath '//node[@resource-id="com.example:id/btnDone"]/@bounds' 2> /dev/null | awk '{$1=$1};1' | awk '{gsub("bounds=", "");print}' | awk '{gsub("\"", "");print}'
, which cleans up the string afterwards and just outputs [294,1877][785,1981]
.
The source of the specific node is:
<node index="1" text="Let’s get started!" resource-id="com.example:id/btnDone" class="android.widget.Button" package="com.example" content-desc="" checkable="false" checked="false" clickable="true" enabled="true" focusable="true" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[294,1877][785,1981]" />
UI automator gives resource IDs, text, and the bounds of the UI element. An XML viewer or Chrome browser can be used to get a better view of the file.
adb pull $(adb shell uiautomator dump | grep -oP '[^ ]+.xml') /tmp/view.xml
The UI element's bounds can be be extracted and the mid point can be calculated. Replace text=
with resource-id=
or content-desc=
as needed.
coords=$(perl -ne 'printf "%d %d\n", ($1+$3)/2, ($2+$4)/2 if /text="MY_BUTTON_TEXT"[^>]*bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/' /tmp/view.xml)
Now we have the coordinates of the UI element's center in $coords
and we just need to send a tap event.
adb shell input tap $coords
I think the best you can do is to inject touch based on a coordinate.
Please see send touch event from ADB to a device and simulating touch using ADB
You might get a coordinate of a button from dumpsys window or activity.
You could also check out Monkeyrunner.