.cursor/skills/android-bug-reproduce/SKILL.md
Reproduce and debug Android bugs on an emulator using ADB. Covers emulator setup, test data seeding, UI navigation via uiautomator, log capture, and screenshots. Use when the user asks to reproduce a bug, debug an issue on an emulator, or investigate an Android crash/behavior.
npx skillsauth add baijum/ukulele-companion android-bug-reproduceInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Systematically reproduce and investigate Android bugs using ADB and the emulator.
emulator and adb on PATHemulator -list-avds)./gradlew assembleDebug if needed)Check for a running emulator first:
adb devices
If none is running, start one:
emulator -list-avds
emulator -avd <avd_name> -no-snapshot-load &
Wait for the device to be ready:
adb wait-for-device
adb shell getprop sys.boot_completed # should return "1"
adb install -r app/build/outputs/apk/debug/app-debug.apk
For features that require existing data (e.g., chord sheets, favorites), seed SharedPreferences directly:
# Stop the app first
adb shell am force-stop com.baijum.ukufretboard
# Write test data to SharedPreferences
adb shell run-as com.baijum.ukufretboard sh -c 'cat > shared_prefs/<pref_file>.xml << '\''XMLEOF'\''
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<map>
<!-- Your test data here -->
</map>
XMLEOF'
Common preference files:
| File | Contents |
|------|----------|
| chord_sheets.xml | Saved songs/chord sheets (JSON list) |
| favorites.xml | Favorited chords |
| app_settings.xml | App settings |
Example — seed a chord sheet:
adb shell run-as com.baijum.ukufretboard sh -c 'cat > shared_prefs/chord_sheets.xml << '\''XMLEOF'\''
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<map>
<string name="chord_sheets_json">[{"id":"test-1","title":"Test Song","artist":"Test","content":"[C]Hello [Am]world\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nLine 8\nLine 9\nLine 10","strumPatternName":"","labels":[],"createdAt":1700000000000,"updatedAt":1700000000000}]</string>
</map>
XMLEOF'
adb shell am start -n com.baijum.ukufretboard/.MainActivity
Dump the current UI tree to find element bounds:
adb shell uiautomator dump /sdcard/ui.xml
adb shell cat /sdcard/ui.xml | head -c 5000 # quick preview
Search for a specific element by content-description or text:
adb shell uiautomator dump /sdcard/ui.xml
adb pull /sdcard/ui.xml /tmp/ui.xml
grep -o 'content-desc="[^"]*"[^/]*bounds="[^"]*"' /tmp/ui.xml
# Open navigation drawer
adb shell uiautomator dump /sdcard/ui.xml
# Find "Open navigation menu" button bounds, then:
adb shell input tap <x> <y>
# Tap by coordinates (center of element bounds)
# bounds="[left,top][right,bottom]" -> tap at ((left+right)/2, (top+bottom)/2)
adb shell input tap 540 960
# Go back
adb shell input keyevent 4
# Enter text in a focused field
adb shell input text "hello"
# Scroll down
adb shell input swipe 540 1500 540 500 300
When the root cause isn't obvious, add temporary Log.d statements to the relevant code:
import android.util.Log
Log.d("DEBUG_<issue>", "state: autoScrolling=$autoScrolling, scrollValue=${scrollState.value}")
Rebuild and reinstall:
./gradlew assembleDebug && adb install -r app/build/outputs/apk/debug/app-debug.apk
# Filter for your debug tag
adb logcat -c # clear old logs
adb logcat -s "DEBUG_<issue>:D" &
# Or capture to file for analysis
adb logcat -s "DEBUG_<issue>:D" > /tmp/debug_log.txt &
Reproduce the bug, then stop logcat and analyze the output.
adb shell screencap -p /sdcard/screenshot.png
adb pull /sdcard/screenshot.png /tmp/screenshot_before.png
For before/after comparison:
# Before fix
adb shell screencap -p /sdcard/before.png
adb pull /sdcard/before.png /tmp/before.png
# After fix (rebuild, reinstall, reproduce)
adb shell screencap -p /sdcard/after.png
adb pull /sdcard/after.png /tmp/after.png
Remove debug logging before committing:
# Find all debug log lines added during this session
grep -rn "DEBUG_<issue>" app/src/main/java/
Remove the Log.d lines and the import android.util.Log if no longer needed.
uiautomator dump before every tap — screen layouts change between devices and orientations; never hardcode coordinates from memory.DEBUG_issue41) so logs don't mix with other debugging sessions.tools
Record scene video clips for a TOML video project. Reads the android.toml or ios.toml to get the scene list and min_clip_duration, navigates to each screen via ADB (Android) or simctl (iOS), and records individual clips. Use when the user says /record-clips and provides a TOML path.
tools
Upload a release AAB to Google Play Store using the Gradle Play Publisher plugin. Use when the user asks to upload to Play Store, publish to Google Play, deploy to internal testing, promote a release, or mentions Play Console.
development
Promote a release from Google Play internal testing to a closed testing track (Alpha or App Hive Testing). Use when the user asks to promote a release, move to closed testing, push to alpha, push to App Hive Testing, or mentions track promotion.
development
Promote a release to Google Play open testing or production tracks. Supports full rollout and staged rollout to production. Use when the user asks to promote to open testing, beta, go to production, release to all users, staged rollout, or increase rollout percentage.