How to Control an Android Phone Without Root¶
You do not need root to control an Android phone from a computer.
You need adb, USB debugging, and a tool that talks to the device through the permissions Android already gives the shell user.
That is the boring answer. It is also the useful one.
Root is a big hammer. It changes the device. It breaks warranty assumptions. It makes test devices different from the phones your users actually carry. For most automation work, you do not want that. You want to tap buttons, type into fields, wait for screens, take screenshots, and move on with your day.
Handsets does that without root.
The setup¶
Start with a normal Android phone or emulator.
Turn on Developer Options, enable USB debugging, and make sure adb devices can see the device. Then install Handsets on your Mac or Linux machine:
Now start a session:
That command connects to the device, forwards a local TCP port, and starts a small on-device daemon through app_process. The daemon runs as the Android shell user. It is not root. It is not an APK. There is no app icon on the phone.
See what can be controlled¶
Ask for the current UI:
On a login screen, the output looks more like a checklist than an XML file:
fill EditText "Email" #email 540,540
fill EditText "Password" #password 540,640 [password]
tap Button "Continue" #continue 540,860
That is the whole point. You do not have to guess coordinates. You can control the device by the words a human sees on screen.
Tap a button by text¶
If there are two Continue buttons, ask Handsets to treat that as a real problem:
If the selector is ambiguous, the command fails instead of tapping a random matching node. That matters when a script is running unattended.
Type into a field¶
hs fill "Email" "you@example.com"
hs fill "Password" "correct-horse-battery-staple"
hs tap "Continue"
hs wait "Welcome" --timeout 15s
This is the usual loop:
- Read the screen.
- Choose a visible label.
- Act on that label.
- Wait for the next screen.
It works well for shell scripts. It also works well for LLM agents, because the UI dump is short enough to feed into a model without drowning it in layout noise.
What "without root" really means¶
It does not mean "without Android security."
Some things are still blocked because Android blocks them for every non-root caller. Secure windows can prevent screenshots. Some system settings are protected. Some app-private data is app-private for a reason.
But normal device control is fair game:
- Tap visible UI.
- Type text.
- Swipe and press navigation keys.
- Read the accessibility tree.
- Wait for text, packages, activities, and idle state.
- Capture screenshots when the current window allows it.
For most QA, RPA, and agent workflows, that is the useful 90%.
The practical tradeoff¶
Root gives you power. It also gives you a fake device.
If your goal is to test how an app behaves on a real user's phone, root can make the test less honest. A no-root workflow keeps the device closer to production while still giving you a fast control surface.
That is why Handsets is built around adb and the shell user. It keeps the setup small, the device normal, and the commands readable.
hs use
hs tap "Sign in"
hs fill "Email" "you@example.com"
hs fill "Password" "$PASSWORD"
hs tap "Continue"
hs wait "Dashboard"
No root. No helper app. No coordinate spreadsheet.