Overview
The Android Emulator Skill provides a comprehensive suite of Python and Bash scripts for automating Android app testing, building, and interaction. Instead of relying on brittle pixel coordinates, it uses accessibility-driven navigation to interact with UI elements semantically (by text, resource ID, or content description).
This skill is optimized for AI agents with minimal token output and structured JSON responses.
When to Use This Skill
Invoke this skill when you need to:
Build and test Android apps programmatically
Launch and interact with Android apps without manual tapping
Navigate UI elements semantically (by text, ID, or class)
Monitor app logs in real-time with intelligent filtering
Perform automated testing workflows
Manage emulator lifecycle (boot, shutdown, list AVDs)
Debug app behavior through UI hierarchy inspection
Quick Start
Verify your environment and launch an app:
# 1. Check that ADB, emulator, and SDK are properly configured
bash scripts/emu_health_check.sh
# 2. Launch the app
python scripts/app_launcher.py --launch com.example.myapp
# 3. Map the current screen to see all interactive elements
python scripts/screen_mapper.py
# 4. Tap a button by its text
python scripts/navigator.py --find-text "Login" --tap
# 5. Enter text into a field
python scripts/navigator.py --find-type EditText --enter-text "[email protected] "
All scripts support --help for detailed options and --json for machine-readable output.
Script Reference
Build and Development
build_and_test.py
Wrapper around Gradle for building projects, running tests, and parsing results.
Usage:
Assemble Debug APK
Run Unit Tests
Install APK
Connected Android Tests
python scripts/build_and_test.py --task assembleDebug
Key Features:
Parses build errors and test failures
Supports --clean for clean builds
JSON output for automated workflows
Detects Gradle wrapper automatically
log_monitor.py
Real-time log monitoring with intelligent filtering and deduplication.
Usage:
Monitor Specific Package
Filter by Tag
Time-Limited Monitoring
JSON Output
python scripts/log_monitor.py --package com.example.myapp
Key Features:
Filters by package, tag, PID, or priority (V, D, I, W, E, F)
Deduplicates repeated log messages
Optional time-limited monitoring with --duration
Structured JSON output for parsing
Log monitoring can generate significant output. Use --priority E or --priority W to focus on errors and warnings during debugging.
Navigation and Interaction
screen_mapper.py
Analyzes the current screen and lists all interactive elements.
Usage:
List Interactive Elements
Verbose Output
JSON Output
python scripts/screen_mapper.py
Output Example:
=== Screen Map ===
[Button] "Login" (resource-id: com.example.myapp:id/login_button)
[EditText] "Email" (resource-id: com.example.myapp:id/email_field)
[EditText] "Password" (resource-id: com.example.myapp:id/password_field)
[TextView] "Forgot password?" (clickable)
Key Features:
Parses UI hierarchy from uiautomator dump
Identifies buttons, text fields, images, and clickable elements
Shows resource IDs, text content, and content descriptions
Foundation for semantic navigation
navigator.py
Finds and interacts with UI elements semantically.
Usage:
Find and Tap by Text
Find by Resource ID
Find EditText and Enter Text
Fuzzy Text Matching
python scripts/navigator.py --find-text "Login" --tap
Key Features:
Fuzzy text matching (case-insensitive, partial matches)
Find by resource ID, class name, or text content
Tap, long-press, and text entry actions
JSON output with element coordinates
If multiple elements match your query, navigator.py will target the first match. Use --find-id for precise targeting when text matching is ambiguous.
gesture.py
Performs swipes, scrolls, and other touch gestures.
Usage:
Swipe Up
Swipe Right
Scroll Down
Custom Swipe Duration
python scripts/gesture.py --swipe up
Key Features:
Directional swipes (up, down, left, right)
Customizable gesture duration
Scroll actions for lists and scrollable content
JSON output with gesture coordinates
keyboard.py
Sends key events and hardware button presses.
Usage:
Press Back Button
Press Home Button
Press Enter
Type Text via ADB
python scripts/keyboard.py --key BACK
Supported Keys:
HOME, BACK, ENTER, TAB, SPACE
VOLUME_UP, VOLUME_DOWN, POWER
MENU, SEARCH, CAMERA
app_launcher.py
Manages app lifecycle: launch, terminate, install, and uninstall.
Usage:
Launch App
Terminate App
Install APK
Uninstall App
List Installed Packages
python scripts/app_launcher.py --launch com.example.myapp
Key Features:
Launch apps via adb shell am start
Force-stop apps to reset state
Install/uninstall APKs programmatically
List all installed packages with --list
Emulator Lifecycle Management
emulator_manage.py
Manages Android Virtual Devices (AVDs).
Usage:
List Available AVDs
Boot Emulator
Shutdown Emulator
JSON Output
python scripts/emulator_manage.py --list
Key Features:
Lists all available AVDs with details
Boots emulators in headless or GUI mode
Gracefully shuts down running emulators
JSON output for scripting
emu_health_check.sh
Verifies that the Android development environment is properly configured.
Usage:
bash scripts/emu_health_check.sh
Checks Performed:
ADB installation and version
Android Emulator availability
Java/OpenJDK installation
Gradle wrapper presence
ANDROID_HOME environment variable
Connected devices and emulators
Output Example:
[✓] ADB found: Android Debug Bridge version 1.0.41
[✓] Emulator found: Android Emulator version 34.1.9
[✓] Java found: openjdk 17.0.8
[✓] Gradle found: Gradle 8.2
[✓] ANDROID_HOME set: /Users/user/Library/Android/sdk
[✓] Connected devices: emulator-5554
Common Patterns
Automated Login Flow
#!/bin/bash
# Launch app
python scripts/app_launcher.py --launch com.example.myapp
# Wait for app to load
sleep 2
# Enter email
python scripts/navigator.py --find-id "com.example.myapp:id/email" --enter-text "[email protected] "
# Enter password
python scripts/navigator.py --find-id "com.example.myapp:id/password" --enter-text "password123"
# Tap login button
python scripts/navigator.py --find-text "Login" --tap
# Monitor logs for errors
python scripts/log_monitor.py --package com.example.myapp --priority E --duration 10
Build and Install Workflow
#!/bin/bash
# Clean and build debug APK
python scripts/build_and_test.py --clean --task assembleDebug
# Install on connected device
python scripts/build_and_test.py --task installDebug
# Launch app
python scripts/app_launcher.py --launch com.example.myapp
UI Testing Workflow
#!/bin/bash
# Map current screen
python scripts/screen_mapper.py --json > screen_map.json
# Find button by text and tap
python scripts/navigator.py --find-text "Next" --tap
# Verify screen changed by mapping again
python scripts/screen_mapper.py --json > screen_map_after.json
# Compare screen maps
diff screen_map.json screen_map_after.json
Auto-Device Detection
All scripts automatically target the single connected device or emulator. If multiple devices are connected, specify the target with:
python scripts/navigator.py -s emulator-5554 --find-text "Login" --tap
Scripts default to concise human-readable output. Use --json for machine-readable output:
screen_mapper.py --json
log_monitor.py --json
{
"elements" : [
{
"type" : "Button" ,
"text" : "Login" ,
"resource_id" : "com.example.myapp:id/login_button" ,
"bounds" : "[100,200][300,250]"
},
{
"type" : "EditText" ,
"text" : "Email" ,
"resource_id" : "com.example.myapp:id/email_field" ,
"bounds" : "[100,150][600,200]"
}
]
}
Key Design Principles
Semantic Navigation
Find elements by meaning , not position :
Text content : “Login”, “Submit”, “Next”
Resource IDs : com.example.myapp:id/login_button
Content descriptions : Accessibility labels
Element types : Button, EditText, TextView
Token Efficiency
Minimize output verbosity for AI agents:
Concise default output
Optional verbose mode with --verbose
Structured JSON with --json for parsing
Zero Configuration
Works with standard Android SDK installations:
Detects ANDROID_HOME automatically
Uses adb from PATH or SDK
Finds Gradle wrapper in project root
Requirements
Android SDK Platform-Tools (adb, fastboot)
Android Emulator
Java / OpenJDK (for Gradle)
Python 3 (for scripts)
Verify setup with:
bash scripts/emu_health_check.sh
Troubleshooting
Issue: “No devices detected”
Cause : No emulator or device connected
Fix : Start emulator or connect physical device:
python scripts/emulator_manage.py --boot Pixel_6_API_34
adb devices
Issue: “Element not found”
Cause : Text, ID, or type doesn’t match any element
Fix : Use screen_mapper.py to inspect current screen:
python scripts/screen_mapper.py --verbose
Issue: “UI hierarchy dump failed”
Cause : App has accessibility services disabled or UI is loading
Fix : Wait for UI to stabilize, then retry:
sleep 2
python scripts/screen_mapper.py
Issue: “Multiple devices connected”
Cause : Multiple emulators or devices detected
Fix : Specify target device with -s:
adb devices # List devices
python scripts/navigator.py -s emulator-5554 --find-text "Login" --tap
Best Practices
Always run emu_health_check.sh before starting automation
Use screen_mapper.py to discover element IDs before scripting
Prefer resource IDs over text for stable element targeting
Add delays (sleep) between interactions for UI stability
Use --json output for parsing in automated workflows
Monitor logs with log_monitor.py during debugging
Target specific devices with -s in multi-device setups
Terminate apps with app_launcher.py --terminate to reset state between tests
Advanced Use Cases
Continuous Integration
Run automated tests in CI/CD pipelines:
#!/bin/bash
set -e
# Start emulator in headless mode
python scripts/emulator_manage.py --boot Pixel_6_API_34 --headless
# Wait for boot
adb wait-for-device
# Build and install
python scripts/build_and_test.py --task assembleDebug
python scripts/build_and_test.py --task installDebug
# Run UI tests
python scripts/app_launcher.py --launch com.example.myapp
python scripts/navigator.py --find-text "Login" --tap
# Shutdown emulator
python scripts/emulator_manage.py --shutdown
Multi-Device Testing
Test across multiple devices in parallel:
#!/bin/bash
for device in $( adb devices | grep -v "List" | awk '{print $1}' ); do
python scripts/navigator.py -s " $device " --find-text "Login" --tap &
done
wait
Stress Testing
Repeatedly interact with app to find edge cases:
#!/bin/bash
for i in { 1..100} ; do
echo "Iteration $i "
python scripts/app_launcher.py --launch com.example.myapp
sleep 2
python scripts/navigator.py --find-text "Submit" --tap
python scripts/app_launcher.py --terminate com.example.myapp
done
References