Quick answer: Connect a phone with USB debugging on, confirm it with adb devices, then run adb install path/to/app.apk. For an update over an existing install, use adb install -r path/to/app.apk.
adb install path/to/app.apk
adb install -r path/to/app.apk
Minimum steps:
- Install SDK Platform Tools and ensure
adbis on your PATH. - On the phone, enable Developer options and USB debugging.
- Connect USB, unlock the phone, accept Allow USB debugging.
- Run
adb devicesand confirm the serial showsdevice, notunauthorized. - Run
adb install path/to/app.apk.
If you ship Android builds from Capacitor or Ionic, this loop is how you put a fresh APK on hardware without waiting on Play Console. For store rollout after testing, see Google Play staged rollouts.
Table of Contents
- Install Platform Tools and verify adb
- Core adb install apk workflow
- adb install flags
- Multiple devices with -s
- Install APK over Wi-Fi
- Split APKs with install-multiple
- Launch the app after install
- Uninstall with adb
- Capacitor example
- Troubleshooting install errors
Install Platform Tools and verify adb
You do not need the full Android Studio download for adb install. You need Platform Tools from Google.
- Download Platform Tools for your OS.
- Unzip to a fixed folder.
- Add that folder to your PATH.
Verify:
adb version
On the device, turn on USB debugging as described in the Android developer options guide. Some OEM skins (Xiaomi MIUI is a common case) also require Install via USB or similar under developer settings.
Use a data cable. Charging-only cables produce empty adb devices lists and waste time.
Core adb install apk workflow
Always check the connection before you install.
adb devices
Expected healthy output:
List of devices attached
XXXXXXXX device
Install:
adb install path/to/your-app.apk
Quote paths that contain spaces. From the APK directory:
adb install app-debug.apk
A successful run typically prints Performing Streamed Install and Success. Under the hood, adb install pushes the file to /data/local/tmp, runs pm install, and removes the temp file. That is simpler than manual adb push plus a shell pm install for everyday testing.
For Capacitor environment setup beyond ADB, see Android setup for Capacitor apps.
adb install flags
| Flag | Meaning | When to use |
|---|---|---|
-r |
Replace existing app, keep data when possible | Debug rebuilds, same package name |
-d |
Allow downgrade on debuggable apps only | Rolling back a debug build over a newer debug build |
-g |
Grant all runtime permissions at install | Faster QA when permissions block launch |
-t |
Allow test-only APKs | Internal testOnly builds from CI |
Common combinations:
adb install -r app-debug.apk
adb install -r -g app-debug.apk
adb install -r -d older-build.apk
adb install -r -t internal-test.apk
-r is the default habit for iterative development. Without it, Android often returns INSTALL_FAILED_ALREADY_EXISTS when the package is already present.
-d allows downgrades only when the installed package is debuggable. It does not downgrade a non-debuggable release from Play. Without -d, a lower versionCode triggers INSTALL_FAILED_VERSION_DOWNGRADE.
-g skips the permission dialog on install. It does not remove the need to test permission flows on a clean install.
-t is required when the manifest sets android:testOnly="true". Without it you get INSTALL_FAILED_TEST_ONLY.
Release builds must be signed consistently. If you generate a new upload key, the Android keystore generator documents fingerprints and PKCS#12 output. Signing with a different key than the installed app produces INSTALL_FAILED_UPDATE_INCOMPATIBLE.
Multiple devices with -s
When more than one device or emulator is attached, adb install may fail with more than one device/emulator. List serials:
adb devices
Target one serial with -s:
adb -s SERIAL install -r app-debug.apk
Replace SERIAL with the value from the first column of adb devices.
Install APK over Wi-Fi
Android 11 and later (Wireless debugging):
Put the phone and computer on the same Wi-Fi network.
- On the phone: Settings → Developer options → Wireless debugging → Pair device with pairing code. Note the pairing IP, port, and six-digit code.
- On the computer, pair:
adb pair IP:PAIRING_PORT
Enter the pairing code when prompted.
- Connect to the debug port shown on the Wireless debugging screen:
adb connect IP:DEBUG_PORT
adb devices
- Unplug USB if both USB and Wi-Fi devices appear in
adb devices, or target Wi-Fi explicitly:
adb -s IP:DEBUG_PORT install -r app-debug.apk
Older Android (USB first):
adb tcpip 5555
adb connect PHONE_IP:5555
Unplug USB after adb devices shows the TCP endpoint. Firewall and network isolation can block Wi-Fi ADB on corporate LANs.
Split APKs with install-multiple
Play Store App Bundles unpack to a base APK plus configuration splits (density, ABI, language) and sometimes install-time feature modules. Install the base APK and every split that matches the target device in one command:
adb install-multiple -r base.apk split_config.xxhdpi.apk split_config.arm64_v8a.apk
Pass only splits from the same bundle extract that fit the connected device. A missing or wrong split causes INSTALL_FAILED_INVALID_APK or incomplete installs.
To sideload from a .apks archive, bundletool install-apks --apks=app.apks is often simpler than listing files by hand.
That is different from ABI split APKs when Gradle builds separate standalone APKs per architecture (app-armeabi-v7a-debug.apk, app-arm64-v8a-debug.apk, and so on). Each of those files is a full app. Pick the one that matches the device CPU and run adb install -r on that single file. Do not pass every APK in the output folder to install-multiple.
Launch the app after install
Known launcher activity (from AndroidManifest.xml):
adb shell am start -n com.example.app/.MainActivity
Quick smoke test when you only know the package name:
adb shell monkey -p com.example.app -c android.intent.category.LAUNCHER 1
monkey fires one launch intent. It is not a full UI test, but it confirms the app opens after install.
View logs:
adb logcat
Uninstall with adb
Remove by package name (not APK path):
adb uninstall com.example.app
This removes the app and its data. Use it for first-launch tests and before fixing a signing mismatch.
To remove the app but leave user data on the device:
adb uninstall -k com.example.app
-k can make the next install reuse old preferences or databases, so skip it when you need a true clean install. Use adb install -r when you only need a faster update loop over an existing install.
Capacitor example
Typical Capacitor loop:
npx cap sync android
Build the debug APK, then:
adb install -r android/app/build/outputs/apk/debug/app-debug.apk
Sign release APKs with your upload key before Play upload. With Play App Signing, store downloads use Google’s app signing certificate, which may differ from your upload certificate. You can update over ADB only when the APK certificate matches the installed app and normal update rules pass. Compare signing certificates before you uninstall. If they differ, test with an APK from an internal testing track (signed like the Play build) instead of a local upload-signed file. Uninstalling the Play build removes app data.
Troubleshooting install errors
| Error or symptom | Likely cause | What to try |
|---|---|---|
unauthorized in adb devices |
RSA prompt not accepted | Unlock phone, approve USB debugging, adb kill-server then adb start-server |
no devices/emulators found |
Cable, driver, or debugging off | New cable, enable USB debugging, Windows Google USB driver if needed |
INSTALL_FAILED_ALREADY_EXISTS |
Same package without -r |
adb install -r app.apk or adb uninstall first |
INSTALL_FAILED_UPDATE_INCOMPATIBLE |
Different signing key | Uninstall old app, or install build signed with same key |
INSTALL_FAILED_VERSION_DOWNGRADE |
Lower versionCode on non-debuggable app | Uninstall, bump version, or use -d only on debuggable packages |
INSTALL_FAILED_INSUFFICIENT_STORAGE |
Low disk space | Free space on device, remove unused apps |
INSTALL_FAILED_TEST_ONLY |
testOnly APK | adb install -t app.apk for trusted test builds only |
INSTALL_FAILED_INVALID_APK |
Corrupt or wrong split set | Rebuild APK, pass all splits to install-multiple |
more than one device/emulator |
Several targets connected | adb -s SERIAL install ... |
device unauthorized
adb devices shows:
XXXXXXXX unauthorized
Fix on the phone, not only in the terminal:
- Replug USB and dismiss the lock screen.
- Tap Allow on Allow USB debugging?
- Check Always allow from this computer for your dev machine.
- Restart ADB:
adb kill-server
adb start-server
adb devices
no devices/emulators found
- Confirm USB debugging is on (see developer options).
- Try another USB port and cable.
- On Windows, install the Google USB driver from SDK Manager if the OEM driver is missing.
- For emulators, start the AVD before
adb install.
INSTALL_FAILED_UPDATE_INCOMPATIBLE
The installed app was signed with a different certificate than the APK you are pushing. Common when mixing debug and release, when Play App Signing holds a different key than your upload APK, or after key rotation.
First confirm you are installing a build signed with the same certificate as the app on the device. Use a Play testing-track APK when you need to match a production install.
If you must replace the install, uninstall deletes app data. Back up anything you need, then:
adb uninstall com.example.app
adb install app.apk
INSTALL_FAILED_VERSION_DOWNGRADE
The APK versionCode is lower than the installed version.
For debuggable packages only, intentional rollback testing:
adb install -r -d older.apk
On release builds from Play, uninstall first or raise versionCode instead of using -d.
INSTALL_FAILED_INSUFFICIENT_STORAGE
The device cannot allocate space for the package. Remove apps or media, then retry. Very large APKs on low-storage test phones hit this often.
INSTALL_FAILED_TEST_ONLY
The build is marked test-only. For your own CI artifacts:
adb install -t -r app.apk
Do not use -t to sideload untrusted APKs.
For Capacitor teams that fix JavaScript, styles, and config without waiting on store review, Capgo supports signed live updates, channels, and rollbacks alongside native store releases.