Make ADB work for you

Lokesh Ponnada
5 min readJun 10, 2019

During the process of becoming a keyboard ninja, I always had a problem operating my android device. Mugging up keyboard shortcuts reduced the use of mouse, but controlling my mobile device was a pain. It was the biggest hindrance in becoming a true keyboard person. In this article, I’ll explain how I used adb to solve few problems [with a demo video at the end]. I feel that every android developer should understand the true potential of adb.

ADB
Short form for “Android Debug Bridge”, adb is a tool that lets you communicate and control an android device. It is built on a client server architecture. It features a lot of commands which serve a diverse set of purposes. But, sadly not many are aware of it’s capabilities. In fact I didn’t realise it’s full power until I worked with AOSP. The only command I used till that time was “adb devices” to check whether my device is connected to the computer. Before proceeding further, look at the commands here . Also note that adb works only on development mode enabled devices

The Problems
1) Device locks every 30 secs
2) I get tons of notifications [For ex, DailyHunt alone presents around 10 notifications a day]
3) I need to launch the app I’m working on frequently
4) Controlling YoutubeMusic app [search/play/skip songs, adjust sound]

You may think that these are small operations and shouldn’t be viewed as problems. But considering that I don’t want to take my hands off the keyboard, these are all annoying. Further, Why do something when your computer can do it for you ?

Lock and Unlock Phone
adb provides a command to send keyevents / text to the device. The typical unlock flow is

# Turn on the screen
adb shell input keyevent KEYCODE_POWER
# Enter the pass code
adb shell input text yourpasscode
# Press Enter
adb shell input keyevent KEYCODE_ENTER

The list of key codes can be found here . Now, lets concatenate the commands and make a short alias in your bash_rc [or bash_profile]. Mine is

alias ul=’adb shell input keyevent KEYCODE_POWER && adb shell input text mypasscode && adb shell input keyevent KEYCODE_ENTER’

Don’t forget to source bash file after the change. Now to unlock your phone, all you need to do is enter ul in the terminal !

2) View/Hide Status bar

#pull status bar
adb shell service call statusbar 1
#collapse status bar
adb shell service call statusbar 2

3) Open/Close an app

#open app : adb shell monkey -p packagename 1
Open gmail => adb shell monkey -p com.google.android.gm 1
#close app :adb shell am force-stop packagename
Close gmail => adb shell am force-stop com.google.android.gm

4 ) Control the YouTube Music App
This is the main reason for writing the article. I was under an impression that adb cannot be used to navigate inside an app, specially a production app. But I was wrong. With little effort, it is entirely possible to use adb as your proxy user. The hack depends on the adb’s tap command which invokes a touch event at a specific location on the screen.

adb shell input tap x y 
Invokes a touch event at coordinates x,y on the screen

The idea is simple. Get the screen coordinates of all the required views. We can then inject touch events by the above command. So, the problem boils down to getting the screen coordinates.
Android has a testing tool called “uiautomator”[Api 18+]. It is designed for cross-app functional UI testing. But for our purpose, we use it to get the layout file of the current activity on the screen along with the coordinates . Problem Solved !!!

# dump the current screen ui
adb shell uiautomator dump
# copy the xml file to computer
adb pull sdcard/window_dump.xml ~/Desktop/

Once the xml file is obtained, look for the element of interest and note the bounded box coordinates of the element. For example, Let us get the location of search bar. It is located on the home page, so look into the xml file of home page. We notice the following element in the xml tree

<node bounds=”[1090,98][1258,266]” checkable=”false” checked=”false” class=”android.widget.ImageButton” clickable=”true” content-desc=”Search” enabled=”true” focusable=”true” focused=”false” index=”1" long-clickable=”false” package=”com.google.android.apps.youtube.music” password=”false” resource-id=”com.google.android.apps.youtube.music:id/action_search_button” scrollable=”false” selected=”false” text=””/>

Observe the parameter ‘bounds’. It has two (x,y) coordinate pairs. The first pair is top-left border and the second pair is bottom-right border of the view. The entire area of the rectangle belongs to the view. This means any tap event in the rectangle triggers the click listener of the view*. And hence

adb shell input tap 1090,98 triggers a tap on search icon

In the above fashion, pull layouts of various activities of your interest, get the bounds of the views that you wish to interact with and stuff all the commands in the computer’s bash file. In my case,

All coordinates are for Pixel 2 XL Device#click search music icon [on home page]
alias sm=’adb shell input tap 1090 98'
#click clear search icon [on search page]
alias cs=’adb shell input tap 1272 98'
#select first result from suggestions [on search page]
alias sf=’adb shell input tap 252 270'
#play first result [on search page]
alias pf=’adb shell input tap 0 668'
#play or pause [on song page]
alias pp=’adb shell input tap 622 2201'
#click next song icon [on song page]
alias ns=’adb shell input tap 881 2215'
#click prev song icon [on song page]
alias ps=’adb shell input tap 391 2215'
#Go to previous page [i..e emulate back key press]
alias gb='adb shell input keyevent KEYCODE_BACK'
#Search for a song [focus should be on search box already]
# Ex: ss songnamewithnospaces
ss(){
adb shell input text “$1”
}
#Change Device volume b/w level 0–25
#Ex, for setting volume to lev 16 : cv 16
cv(){
adb shell media volume — set “$1”
}

The shortcomings with this approach are
1) The coordinates differ for each device [ can be handled with scripting ]
2) Layout might change in an app update forcing to repeat the process

This is it. Now I don’t need to take my hands off the keyboard to skip that boring song or play some random song or even mute the audio. I also automated few things like “Shopping from Myntra” , “Availing Tatkal Tickets [debatable from ethical perspective]”, “Reading Quora” etc..

Finally I realised that ADB is a Swiss army knife.

--

--