Of course! Let's dive deep into UIAutomator for Python.

This is a very common requirement for Android automation. Here's a complete guide covering what it is, why you'd use it, how to set it up, and how to write scripts with clear examples.
What is UIAutomator?
UIAutomator is a UI testing framework for Android. It allows you to test user interfaces and perform operations like clicks, swipes, and text entry on your Android device or emulator from an external script.
Key Characteristics:
- Cross-App: It can interact with any application on the device, not just the one being tested. This is great for tasks like launching a dialer from your app or checking system notifications.
- View-Based: It interacts with UI elements based on their View properties, such as
text,resource-id,content-description, andclass. This is more stable than using coordinates, which can change with different screen resolutions. - Java/Kotlin Origins: UIAutomator was originally part of the Android SDK and written in Java. The Python community has created excellent libraries to wrap this Java functionality, making it accessible to Python developers.
Why Use UIAutomator with Python?
You would choose UIAutomator for Python when you need to:

- Perform End-to-End (E2E) Testing: Automate a complete user flow, from app launch to a final confirmation.
- Interact with System UI: Click on notifications, toggle system settings, interact with the launcher, etc.
- Write Scripts for Complex Scenarios: For tasks like installing an APK, running your app, and then verifying its behavior.
- Leverage Python's Ecosystem: Use Python's powerful libraries for data analysis (
pandas), reporting (pytest-html), or task scheduling (cron/APScheduler).
The Main Python Libraries for UIAutomator
There are two primary libraries you'll encounter. For new projects, uiautomator2 is the recommended choice.
| Library | Description | Pros | Cons |
|---|---|---|---|
uiautomator2 |
A modern, actively maintained fork of the original uiautomator. It's more powerful and easier to set up. |
- Easy setup (handles driver installation) - More features (WiFi ADB, screen recording, app installation) - Active community & development - Better error handling |
- Slightly different API from the original. |
pure-python-uiautomator |
A more direct Python wrapper around the original Java UIAutomator library. | - Closer to the original Java API - Good for simple, direct tasks |
- Complex setup (requires manual driver installation) - Less actively maintained - Fewer advanced features |
Recommendation: Start with uiautomator2. It's the future-proof and more user-friendly option.
Step-by-Step Guide with uiautomator2
This is the most common and recommended workflow.
Step 1: Prerequisites
- Python: Ensure you have Python 3.6+ installed.
- Android Device or Emulator:
- Device: Enable "USB Debugging" in Developer Options.
- Emulator: Create an Android Virtual Device (AVD) in Android Studio with Google Play Services.
- ADB (Android Debug Bridge): Make sure
adbis in your system's PATH and can see your device. You can test this by runningadb devicesin your terminal. You should see your device/emulator listed.
Step 2: Installation
Install the uiautomator2 library using pip.

pip install --pre uiautomator2
Step 3: Initial Setup on the Device
This is the most crucial step. You need to install a helper APK on your device/emulator that will act as a bridge between your Python script and the Android UI.
Run the following command in your terminal:
python -m uiautomator2 init
This command will:
- Check for a connected device.
- Push the
uiautomator2helper APK to your device. - Install it.
- Grant the necessary permissions.
You should see output similar to this:
[INFO] uiautomator2 version 2.16.21
[INFO] install apk: /Users/user/.pyenv/versions/3.9.6/lib/python3.9/site-packages/uiautomator2/inject/__pycache__/uiautomator2-2.16.21-py3-none-any.whl
[INFO] installed version: 2.16.21
...
[INFO] init success
Step 4: Your First Python Script
Now you can write Python code to control your device!
Connect to the device:
import uiautomator2 as u2
# Connect to the device via USB (or WiFi, see next section)
d = u2.connect()
# Or for a specific device serial
# d = u2.connect("emulator-5554")
print("Device connected successfully!")
print(f"Device name: {d.info['productName']}")
print(f"Screen resolution: {d.info['displayWidth']}x{d.info['displayHeight']}")
Performing Actions (Examples):
Let's automate a simple sequence: opening the Settings app, finding "About phone", and clicking it.
import uiautomator2 as u2
import time
# Connect to the device
d = u2.connect()
print("Starting automation script...")
# 1. Launch the Settings app
print("Launching Settings app...")
d.app_start("com.android.settings")
time.sleep(3) # Wait for the app to load
# 2. Find and click the "About phone" element
# We can find it by its text.
print("Finding 'About phone'...")
about_phone_element = d(text="About phone")
# Check if the element exists before clicking
if about_phone_element.exists:
print("Element found. Clicking it...")
about_phone_element.click()
time.sleep(2)
print("Successfully clicked 'About phone'.")
else:
print("Error: 'About phone' element not found!")
# 3. Get the text of the "Model number" field
print("Getting model number...")
model_number_element = d(text="Model number")
if model_number_element.exists:
# The actual value is in the sibling element
model_value = model_number_element.sibling(className='android.widget.TextView').get_text()
print(f"Model Number: {model_value}")
# 4. Go back to the previous screen
print("Pressing back button...")
d.press("back")
# 5. Stop the Settings app
print("Stopping Settings app...")
d.app_stop("com.android.settings")
print("Script finished.")
Advanced uiautomator2 Features
A. Connecting over WiFi
For faster execution, you can connect your device over WiFi after the initial USB setup.
- Make sure your device and computer are on the same WiFi network.
- On your device, open the
UIAutomator2app (it was installed in theinitstep). - Note the IP address displayed in the app (e.g.,
168.1.10:5555). - Connect from Python using this IP:
import uiautomator2 as u2
# Connect using the IP:PORT from the app
d = u2.connect("http://192.168.1.10:5555")
B. Screen Recording
It's incredibly useful to record your script's execution to debug failures.
import uiautomator2 as u2
import time
d = u2.connect()
# Start recording
d.screenrecord.start("my_recording.mp4")
# --- Your automation steps here ---
d.app_start("com.android.settings")
d(text="About phone").click()
time.sleep(3)
# -------------------------------
# Stop recording. The video file will be on your computer.
video_path = d.screenrecord.stop()
print(f"Recording saved to: {video_path}")
C. Handling Toast Messages
Toast messages are those small pop-ups that appear at the bottom of the screen.
# Enable toast detection (must be called before toasts appear)
d.toast.show_debug = True # Shows toasts in logcat
d.toast.reset() # Clear any previous toasts
# Perform an action that might show a toast
d.press("home")
d(resourceId="com.android.launcher:id/search_button").click()
# Wait for a specific toast message to appear
try:
# Wait up to 10 seconds for the toast
toast_message = d.toast.get_message(10, default=None)
if toast_message:
print(f"Found Toast: {toast_message}")
else:
print("Toast message did not appear.")
except Exception as e:
print(f"Error getting toast: {e}")
# Clear the toast message from the buffer
d.toast.reset()
Finding Element Selectors
The key to robust automation is finding the right elements. Here are the common ways to do it with uiautomator2.
You can use d.dump_hierarchy() to print the current UI layout to your console, which is great for finding resource-ids and other properties.
| Selector | Description | Example |
|---|---|---|
d(text="Settings") |
Finds an element with the exact visible text. | d(text="Wi-Fi").click() |
d(textContains="net") |
Finds an element whose text contains the substring. | d(textContains="net").click() |
d(textStartsWith="Set") |
Finds an element whose text starts with the prefix. | d(textStartsWith="Set").click() |
d(description="Search") |
Finds an element with the content-description attribute. |
d(description="Search").click() |
d(resourceId="com.android.settings:id/title") |
(Most Robust) Finds an element by its unique resource ID. | d(resourceId="com.android.settings:id/title").click() |
d(className="android.widget.TextView") |
Finds all elements of a certain class (e.g., TextView, Button). | d(className="android.widget.Button")[0].click() |
| Combination | Combine selectors for more precision. | d(text="About", className="android.widget.TextView").click() |
Pro-Tip: Use the uiautomator2 helper app on your device to easily inspect elements and get their resource-id, text, and other properties.
