--- name: run-app description: Use to build, install, and launch ApkAnalyzer on a connected device or emulator, or to verify a code change actually works at runtime rather than just compiling. Triggered by phrases like "run the app", "install on device", "launch the app", "try it on my phone", "deploy to device", "see if this works", "run it". --- # Skill: Build, Install, and Run ApkAnalyzer on a Device > Debug builds and any release build the user already has installed share the same > `applicationId` (`sk.styk.martin.apkanalyzer` — no debug suffix), so installing over an existing > release can hit a version conflict. Read Step 3 before installing, especially the first time on > a given device. ## Step 1 — Find `adb` `adb` is often not on `PATH`. Try it directly first; if that fails, it lives under the Android SDK: ```bash adb devices -l || "$ANDROID_HOME/platform-tools/adb" devices -l # macOS/Linux ``` ```powershell adb devices -l 2>$null; if (-not $?) { & "$env:ANDROID_HOME\platform-tools\adb.exe" devices -l } ``` If `ANDROID_HOME` isn't set either, see the `setup-local-tools` skill. Confirm at least one device/emulator is listed as `device` (not `unauthorized` or `offline`) before continuing. If multiple devices are attached, target one explicitly with `-s ` on every `adb` command below. ## Step 2 — Build and install ```bash ./gradlew installDebug ``` This assembles `:app:debug` and installs it via the AGP-managed install task. If it succeeds, skip to Step 4. ## Step 3 — If install fails with `INSTALL_FAILED_VERSION_DOWNGRADE` This happens when the device already has a build with a **higher** `versionCode` than the debug build's `versionCode = 1` (see `app/build.gradle.kts`) — typically a release build (from the Play Store, a manual release, or a prior CI artifact) already on the device. 1. Check whether `-d` (allow downgrade) is enough — **it only works if the existing install is itself debuggable**, so this recovers cleanly with no data loss when the device already has a debug build: ```bash adb install -r -d app/build/outputs/apk/debug/app-debug.apk ``` 2. If that still fails (the existing install is a non-debuggable release build), the only way to get the debug build on is to uninstall first — **and this wipes the app's local data** (DataStore prefs: recently-viewed apps, search history, color scheme). **Ask the user before doing this** — it's exactly the kind of hard-to-reverse action that needs confirmation, not an assumption: ```bash adb uninstall sk.styk.martin.apkanalyzer ./gradlew installDebug ``` ## Step 4 — Launch and verify it's actually running Installing is not running. Launch the main activity and confirm the process is alive with no immediate crash: ```bash adb shell am start -n sk.styk.martin.apkanalyzer/.ui.ApkAnalyzerActivity sleep 2 adb shell pidof sk.styk.martin.apkanalyzer # a PID means it's running; empty means it crashed on launch ``` If `pidof` comes back empty, pull the crash from logcat rather than guessing: ```bash adb logcat -d -t 200 | grep -A 30 "FATAL EXCEPTION" ``` ## Verification - [ ] `adb devices -l` showed a `device` (not `unauthorized`/`offline`) before installing - [ ] Install succeeded — either directly, or via the `-r -d` / uninstall path in Step 3, with explicit user confirmation before any uninstall - [ ] App launched via `am start` and `pidof` returned a PID (not empty) - [ ] For a specific feature/screen change: actually navigated to it in the running app, not just confirmed the process didn't crash on the launch screen — see the `navigate-app-adb` skill to do this via `adb` instead of a human tapping through the device