# Running Android App on a Physical Device **Author**: Matthew Raymer **Last Updated**: 2026-02-12 **Version**: 1.0.0 ## Overview This guide demonstrates how to run the DailyNotification plugin test app on a physical Android device. Physical device testing is essential for validating: - **Real notification behavior** — Emulators may not accurately simulate notification delivery timing - **Battery optimization effects** — OEM-specific power management that affects background tasks - **Actual alarm scheduling** — AlarmManager behavior varies between emulators and real hardware - **Device reboot persistence** — Boot receivers and alarm recovery ## Prerequisites ### Required Hardware - **Android phone or tablet** running Android 8.0 (API 26) or higher - **USB cable** (data-capable, not charge-only) - **Development computer** with USB port ### Required Software - **Android SDK** with platform-tools (provides `adb`) - **Gradle** (via Gradle Wrapper) - **Node.js** and **npm** (for TypeScript compilation) ### How to Check | Requirement | How to check | |------------------|--------------| | **Node.js** | `node --version` (v14+ recommended; test app may require 20+) | | **npm** | `npm --version` | | **Java** | `java -version` (Java 11+) | | **ANDROID_HOME** | `echo $ANDROID_HOME` (must be set to your Android SDK root) | | **adb** | `adb version` (must be on PATH) | **Project script:** From the repo root: ```bash node scripts/check-environment.js ``` ## Step 1: Enable Developer Options on Your Phone Developer Options are hidden by default. To enable them: ### Android 8.0 - 14 (Most Devices) 1. Open **Settings** 2. Scroll down to **About phone** (or **About device**) 3. Find **Build number** 4. **Tap Build number 7 times** rapidly 5. You'll see "You are now a developer!" toast message ### Samsung Devices 1. **Settings** → **About phone** → **Software information** 2. Tap **Build number** 7 times ### Xiaomi/MIUI Devices 1. **Settings** → **About phone** 2. Tap **MIUI version** 7 times ### OnePlus Devices 1. **Settings** → **About phone** 2. Tap **Build number** 7 times ## Step 2: Enable USB Debugging After enabling Developer Options: 1. Go to **Settings** → **System** → **Developer options** - On some phones: **Settings** → **Developer options** directly 2. Scroll to find **USB debugging** 3. Toggle **USB debugging ON** 4. Confirm when prompted ### Optional but Recommended Settings While in Developer Options, also enable: - **Stay awake** — Screen stays on while charging (useful during development) - **Allow mock locations** — If testing location features ## Step 3: Connect and Authorize Your Device ### Physical Connection 1. Connect your phone to your computer via USB 2. On your phone, change USB mode: - Pull down notification shade - Tap the USB notification ("Charging this device via USB") - Select **File transfer / Android Auto** or **PTP** (not "Charge only") ### Authorize Computer 1. On your phone, you'll see a dialog: **"Allow USB debugging?"** 2. Check **"Always allow from this computer"** (recommended) 3. Tap **Allow** ### Verify Connection ```bash # List connected devices adb devices # Expected output: # List of devices attached # ABC123DEF456 device ``` **Troubleshooting connection states:** | State | Meaning | Solution | |-------|---------|----------| | `device` | Connected and authorized | Ready to use | | `unauthorized` | USB debugging not authorized | Check phone for auth dialog | | `offline` | Connection issues | Unplug, replug, restart adb | | (empty) | Device not detected | Check USB cable, USB mode | ## Step 4: Build and Install the App ### Option A: Using Build Script (Recommended) From the `test-apps/daily-notification-test` directory: ```bash # Build and run on connected device ./scripts/build.sh --run-android ``` ### Option B: Manual Build ```bash # 1. Navigate to test app directory cd test-apps/daily-notification-test # 2. Build web assets npm run build # 3. Sync with Capacitor npm run cap:sync:android # 4. Build APK cd android ./gradlew :app:assembleDebug # 5. Install on device adb install -r app/build/outputs/apk/debug/app-debug.apk # 6. Launch app adb shell am start -n org.timesafari.dailynotification.test/.MainActivity ``` ### Option C: Using Capacitor CLI ```bash # Build, install, and launch in one command npx cap run android --target # Get device ID from: adb devices ``` ## Step 5: Configure Battery Optimization (Critical!) **This is the most important step for notification testing.** Android OEMs aggressively kill background apps to save battery. Without proper configuration, your alarms and notifications may not fire. ### Disable Battery Optimization for Test App 1. **Settings** → **Apps** → **DailyNotification Test** (or your app name) 2. **Battery** → **Unrestricted** or **Don't optimize** ### Manufacturer-Specific Settings #### Samsung (One UI) 1. **Settings** → **Battery** → **Background usage limits** 2. Remove app from "Sleeping apps" and "Deep sleeping apps" 3. Add app to "Never sleeping apps" #### Xiaomi (MIUI) 1. **Settings** → **Apps** → **Manage apps** → Select app 2. Enable **Autostart** 3. **Battery saver** → **No restrictions** 4. **Security** app → **Permissions** → **Autostart** → Enable for app #### OnePlus (OxygenOS) 1. **Settings** → **Battery** → **Battery optimization** 2. Select app → **Don't optimize** 3. **Settings** → **Apps** → Select app → **Advanced** → **Optimize battery usage** → Off #### Huawei/Honor (EMUI) 1. **Settings** → **Battery** → **App launch** 2. Disable automatic management for the app 3. Enable all three toggles: Auto-launch, Secondary launch, Run in background #### Oppo/Realme (ColorOS) 1. **Settings** → **Battery** → **More battery settings** 2. **Optimize battery use** → Select app → **Don't optimize** 3. Enable **Allow auto-start** and **Allow background activity** ### Verify Battery Settings ```bash # Check if app is whitelisted from battery optimization adb shell dumpsys deviceidle whitelist # Should include your package name ``` ## Step 6: Monitor Logs ### Real-time Log Streaming ```bash # All logs from the app adb logcat | grep -E "DailyNotification|Capacitor|Console" # Specific tags only adb logcat -s "DailyNotification" "Capacitor" "Console" # Clear logs and start fresh adb logcat -c && adb logcat -s "DailyNotification" ``` ### Filter by Log Level ```bash # Errors only adb logcat *:E | grep DailyNotification # Warnings and above adb logcat *:W | grep DailyNotification # Verbose (all levels) adb logcat *:V | grep DailyNotification ``` ### Save Logs to File ```bash # Stream logs to file adb logcat -s "DailyNotification" > device_logs.txt # Press Ctrl+C to stop ``` ### Check Alarm Scheduling ```bash # View scheduled alarms (requires root or debuggable build) adb shell dumpsys alarm | grep -A 5 "org.timesafari" # View alarm statistics adb shell dumpsys alarm | grep -i "daily" ``` ## Step 7: Testing Notification Features ### Test Immediate Notification 1. Open the app 2. Navigate to notification testing section 3. Trigger an immediate notification 4. Verify it appears in the notification tray ### Test Scheduled Notification 1. Schedule a notification for 1-2 minutes in the future 2. Lock the phone or put app in background 3. Wait for notification to fire 4. Check logs if notification doesn't appear ### Test Alarm Persistence 1. Schedule a notification 2. Reboot the device: ```bash adb reboot ``` 3. After reboot, check if alarm was restored: ```bash adb shell dumpsys alarm | grep -A 5 "org.timesafari" ``` ### Test Force Stop Recovery 1. Schedule a notification 2. Force stop the app: ```bash adb shell am force-stop org.timesafari.dailynotification.test ``` 3. Check if alarms are recovered (implementation dependent) ## Complete Command Sequence ### Quick Start (Copy-Paste Ready) ```bash # 1. Verify device connection adb devices # 2. Navigate to test app cd test-apps/daily-notification-test # 3. Build everything npm run build npm run cap:sync:android # 4. Build and install APK cd android ./gradlew :app:assembleDebug adb install -r app/build/outputs/apk/debug/app-debug.apk # 5. Launch app adb shell am start -n org.timesafari.dailynotification.test/.MainActivity # 6. Monitor logs (in separate terminal) adb logcat -s "DailyNotification" "Capacitor" "Console" ``` ## Troubleshooting ### Device Not Detected ```bash # Restart ADB server adb kill-server adb start-server adb devices # Check USB connection # - Try different USB cable (use data cable, not charge-only) # - Try different USB port # - Check USB mode on phone (should be File transfer, not Charge only) ``` ### "Unauthorized" Device ```bash # Revoke USB debugging authorizations on phone: # Settings → Developer options → Revoke USB debugging authorizations # Then reconnect and re-authorize adb kill-server adb start-server # Accept authorization dialog on phone ``` ### APK Installation Fails ```bash # Error: INSTALL_FAILED_UPDATE_INCOMPATIBLE # Solution: Uninstall existing app first adb uninstall org.timesafari.dailynotification.test adb install app/build/outputs/apk/debug/app-debug.apk # Error: INSTALL_FAILED_USER_RESTRICTED # Solution: Enable "Install via USB" in Developer options ``` ### Notifications Not Appearing 1. **Check notification permissions:** ```bash adb shell dumpsys notification | grep -A 10 "org.timesafari" ``` 2. **Check battery optimization:** - Ensure app is set to "Unrestricted" or "Don't optimize" - Check manufacturer-specific settings (see Step 5) 3. **Check Do Not Disturb:** - Ensure DND is off, or app is allowed through DND 4. **Check notification channel:** ```bash adb shell dumpsys notification | grep -B 5 -A 10 "channel" ``` ### Alarms Not Firing 1. **Check if alarms are scheduled:** ```bash adb shell dumpsys alarm | grep -A 10 "org.timesafari" ``` 2. **Check Doze mode:** ```bash # Check current Doze state adb shell dumpsys deviceidle # Force device out of Doze for testing adb shell dumpsys deviceidle unforce ``` 3. **Check exact alarm permission (Android 12+):** ```bash adb shell appops get org.timesafari.dailynotification.test SCHEDULE_EXACT_ALARM ``` ### Build Failures ```bash # Clean build cd android ./gradlew clean ./gradlew :app:assembleDebug # If still failing, clean Gradle cache rm -rf ~/.gradle/caches ./gradlew :app:assembleDebug ``` ## Benefits of Physical Device Testing ### Advantages Over Emulator - ✅ **Accurate notification timing** — Real hardware scheduler behavior - ✅ **Real battery optimization** — Test against actual OEM restrictions - ✅ **True Doze mode** — Emulators simulate but don't fully replicate - ✅ **Boot receiver testing** — Actual device reboot behavior - ✅ **Performance metrics** — Real CPU/memory usage - ✅ **User experience** — How notifications actually feel ### When to Use Physical Device - **Final validation** — Before release - **Notification timing tests** — Alarm accuracy verification - **Battery impact testing** — Real power consumption - **Reboot persistence tests** — Boot receiver validation - **OEM-specific testing** — Samsung, Xiaomi, etc. quirks ### When Emulator is Sufficient - **Basic functionality** — Core feature development - **UI testing** — Layout and interaction testing - **Quick iteration** — Fast build-test cycles - **CI/CD pipelines** — Automated testing ## Multiple Device Management ### List All Connected Devices ```bash adb devices -l # Example output: # ABC123DEF456 device usb:1-1 product:walleye model:Pixel_2 device:walleye # XYZ789GHI012 device usb:1-2 product:star2lte model:SM_G965F device:star2lte ``` ### Target Specific Device ```bash # Install on specific device adb -s ABC123DEF456 install -r app/build/outputs/apk/debug/app-debug.apk # View logs from specific device adb -s ABC123DEF456 logcat -s "DailyNotification" # Launch app on specific device adb -s ABC123DEF456 shell am start -n org.timesafari.dailynotification.test/.MainActivity ``` ## Wireless ADB (Optional) For cable-free development after initial setup: ```bash # 1. Connect device via USB first # 2. Enable TCP/IP mode on port 5555 adb tcpip 5555 # 3. Find device IP (Settings → About phone → Status → IP address) # Or: adb shell ip addr show wlan0 | grep inet # 4. Disconnect USB and connect wirelessly adb connect 192.168.1.100:5555 # 5. Verify connection adb devices # Should show: 192.168.1.100:5555 device ``` **Note:** Wireless ADB is slower than USB and may disconnect. Use USB for large APK transfers. ## Next Steps ### Testing Workflow 1. **Build** → Make changes, rebuild APK 2. **Install** → Push to device with `adb install -r` 3. **Test** → Exercise notification features 4. **Monitor** → Watch logs for issues 5. **Iterate** → Fix and repeat ### Recommended Test Sequence 1. ✅ Immediate notification display 2. ✅ Scheduled notification (1-2 min delay) 3. ✅ App backgrounded notification 4. ✅ Screen off notification 5. ✅ Device reboot alarm persistence 6. ✅ Force stop recovery (if implemented) 7. ✅ Battery optimization scenarios --- **Physical device testing is essential for production-quality notification behavior.** While emulators are great for development, only real hardware reveals the true behavior of Android's notification and alarm systems. 📱