diff --git a/BUILDING.md b/BUILDING.md index a782d400..92e08ea1 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -1301,7 +1301,8 @@ npm run build:android:test:run # test env build, install, launch ##### Reference -- Full troubleshooting and options: [doc/android-emulator-deployment-guide.md](doc/android-emulator-deployment-guide.md) +- Emulator troubleshooting and options: [doc/android-emulator-deployment-guide.md](doc/android-emulator-deployment-guide.md) +- **Physical device testing**: [doc/android-physical-device-guide.md](doc/android-physical-device-guide.md) #### Android Build Commands @@ -1811,6 +1812,8 @@ npm run build:android:assets - [Electron Build Patterns](docs/electron-build-patterns.md) - [iOS Build Scripts](docs/ios-build-scripts.md) - [Android Build Scripts](docs/android-build-scripts.md) +- [Android Physical Device Guide](doc/android-physical-device-guide.md) +- [Android Emulator Deployment Guide](doc/android-emulator-deployment-guide.md) - [Web Build Scripts](docs/web-build-scripts.md) - [Build Troubleshooting](docs/build-troubleshooting.md) diff --git a/doc/android-physical-device-guide.md b/doc/android-physical-device-guide.md new file mode 100644 index 00000000..22ddba76 --- /dev/null +++ b/doc/android-physical-device-guide.md @@ -0,0 +1,515 @@ +# Android Physical Device Deployment Guide + +**Author**: Matthew Raymer +**Date**: 2025-02-12 +**Status**: 🎯 **ACTIVE** - Complete guide for deploying TimeSafari to physical Android devices + +## Overview + +This guide provides comprehensive instructions for building and deploying TimeSafari to physical Android devices for testing and development. Unlike emulator testing, physical device testing requires additional setup for USB connections and network configuration. + +## Prerequisites + +### Required Tools + +1. **Android SDK Platform Tools** (includes `adb`) + ```bash + # macOS (Homebrew) + brew install android-platform-tools + + # Or via Android SDK Manager + sdkmanager "platform-tools" + ``` + +2. **Node.js 18+** and npm + +3. **Java Development Kit (JDK) 17+** + ```bash + # macOS (Homebrew) + brew install openjdk@17 + + # Verify installation + java -version + ``` + +### Environment Setup + +Add to your shell configuration (`~/.zshrc` or `~/.bashrc`): + +```bash +# Android SDK location +export ANDROID_HOME=$HOME/Library/Android/sdk # macOS default +# export ANDROID_HOME=$HOME/Android/Sdk # Linux default + +export PATH=$PATH:$ANDROID_HOME/platform-tools +export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin +export PATH=$PATH:$ANDROID_HOME/build-tools/34.0.0 +``` + +Reload your shell: + +```bash +source ~/.zshrc # or source ~/.bashrc +``` + +Verify installation: + +```bash +adb version +``` + +## Device Setup + +### Step 1: Enable Developer Options + +Developer Options is hidden by default on Android devices. To enable it: + +1. Open **Settings** on your Android device +2. Scroll down and tap **About phone** (or **About device**) +3. Find **Build number** and tap it **7 times** rapidly +4. You'll see a message: "You are now a developer!" +5. Go back to Settings - **Developer options** now appears + +### Step 2: Enable USB Debugging + +1. Go to **Settings** → **Developer options** +2. Enable **USB debugging** (toggle it ON) +3. Optionally enable these helpful options: + - **Stay awake** - Screen stays on while charging + - **Install via USB** - Allow app installations via USB + +### Step 3: Connect Your Device + +1. Connect your Android device to your computer via USB cable +2. On your device, you'll see a prompt: "Allow USB debugging?" +3. Check **"Always allow from this computer"** (recommended) +4. Tap **Allow** + +### Step 4: Verify Connection + +```bash +# List connected devices +adb devices + +# Expected output: +# List of devices attached +# XXXXXXXXXX device +``` + +If you see `unauthorized` instead of `device`, check your phone for the USB debugging authorization prompt. + +## Network Configuration for Development + +### Understanding the Network Challenge + +When running a local development server on your computer: +- **Emulators** use `10.0.2.2` to reach the host machine +- **Physical devices** need your computer's actual LAN IP address + +### Step 1: Find Your Computer's IP Address + +```bash +# macOS +ipconfig getifaddr en0 # Wi-Fi +# or +ipconfig getifaddr en1 # Ethernet + +# Linux +hostname -I | awk '{print $1}' +# or +ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1 +``` + +Example output: `192.168.1.100` + +### Step 2: Ensure Same Network + +Your Android device and computer **must be on the same Wi-Fi network** for the device to reach your local development servers. + +### Step 3: Configure API Endpoints + +Create or edit `.env.development` with your computer's IP: + +```bash +# .env.development - for physical device testing +VITE_DEFAULT_ENDORSER_API_SERVER=http://192.168.1.100:3000 +VITE_DEFAULT_PARTNER_API_SERVER=http://192.168.1.100:3000 +VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app +VITE_APP_SERVER=http://192.168.1.100:8080 +``` + +**Important**: Replace `192.168.1.100` with your actual IP address. + +### Step 4: Start Your Local Server + +If testing against local API servers, ensure they're accessible from the network: + +```bash +# Start your API server bound to all interfaces (not just localhost) +# Example for Node.js: +node server.js --host 0.0.0.0 + +# Or configure your server to listen on 0.0.0.0 instead of 127.0.0.1 +``` + +### Alternative: Use Test/Production Servers + +For simpler testing without local servers, use the test environment: + +```bash +# Build with test API servers (no local server needed) +npm run build:android:test +``` + +## Building and Deploying + +### Quick Start (Recommended) + +```bash +# 1. Verify device is connected +adb devices + +# 2. Build and deploy in one command +npm run build:android:debug:run +``` + +### Step-by-Step Deployment + +#### Step 1: Build the App + +```bash +# Development build (uses .env.development) +npm run build:android:dev + +# Test build (uses test API servers) +npm run build:android:test + +# Production build +npm run build:android:prod +``` + +#### Step 2: Install the APK + +```bash +# Install (replace existing if present) +adb install -r android/app/build/outputs/apk/debug/app-debug.apk +``` + +#### Step 3: Launch the App + +```bash +# Start the app +adb shell am start -n app.timesafari.app/app.timesafari.MainActivity +``` + +### One-Line Deploy Commands + +```bash +# Development build + install + launch +npm run build:android:debug:run + +# Test build + install + launch +npm run build:android:test:run + +# Deploy to connected device (build must exist) +npm run build:android:deploy +``` + +## Debugging + +### View App Logs + +```bash +# All logs from your app +adb logcat | grep -E "(TimeSafari|Capacitor)" + +# With color highlighting +adb logcat | grep -E "(TimeSafari|Capacitor)" --color=always + +# Save logs to file +adb logcat > device-logs.txt +``` + +### Chrome DevTools (Remote Debugging) + +1. Open Chrome on your computer +2. Navigate to `chrome://inspect` +3. Your device should appear under "Remote Target" +4. Click **inspect** to open DevTools for your app + +**Requirements**: +- USB debugging must be enabled +- Device must be connected via USB +- App must be a debug build + +### Common Log Filters + +```bash +# Network-related issues +adb logcat | grep -i "network\|http\|socket" + +# JavaScript errors +adb logcat | grep -i "console\|error\|exception" + +# Capacitor plugin issues +adb logcat | grep -i "capacitor" + +# Detailed app logs +adb logcat -s "TimeSafari:V" +``` + +## Troubleshooting + +### Device Not Detected + +**Symptom**: `adb devices` shows nothing or shows `unauthorized` + +**Solutions**: + +1. **Check USB cable**: Some cables are charge-only. Use a data-capable USB cable. + +2. **Revoke USB debugging authorizations** (on device): + - Settings → Developer options → Revoke USB debugging authorizations + - Reconnect and re-authorize + +3. **Restart ADB server**: + ```bash + adb kill-server + adb start-server + adb devices + ``` + +4. **Try different USB port**: Some USB hubs don't work well with ADB. + +5. **Check device USB mode**: Pull down notification shade and ensure USB is set to "File Transfer" or "MTP" mode, not just charging. + +### App Can't Connect to Local Server + +**Symptom**: App loads but shows network errors or can't reach API + +**Solutions**: + +1. **Verify IP address**: + ```bash + # Make sure you have the right IP + ipconfig getifaddr en0 # macOS + ``` + +2. **Check firewall**: Temporarily disable firewall or add exception for port 3000 + +3. **Test connectivity from device**: + - Open Chrome on your Android device + - Navigate to `http://YOUR_IP:3000` + - Should see your API response + +4. **Verify server is listening on all interfaces**: + ```bash + # Should show 0.0.0.0:3000, not 127.0.0.1:3000 + lsof -i :3000 + ``` + +5. **Same network check**: Ensure phone Wi-Fi and computer are on the same network + +### Installation Failed + +**Symptom**: `adb install` fails with error + +**Common errors and solutions**: + +1. **INSTALL_FAILED_UPDATE_INCOMPATIBLE**: + ```bash + # Uninstall existing app first + adb uninstall app.timesafari.app + adb install android/app/build/outputs/apk/debug/app-debug.apk + ``` + +2. **INSTALL_FAILED_INSUFFICIENT_STORAGE**: + - Free up space on the device + - Or install to SD card if available + +3. **INSTALL_FAILED_USER_RESTRICTED**: + - Enable "Install via USB" in Developer options + - On some devices: Settings → Security → Unknown sources + +4. **Signature mismatch**: + ```bash + # Full clean reinstall + adb uninstall app.timesafari.app + npm run clean:android + npm run build:android:debug + adb install android/app/build/outputs/apk/debug/app-debug.apk + ``` + +### App Crashes on Launch + +**Symptom**: App opens briefly then closes + +**Debug steps**: + +1. **Check crash logs**: + ```bash + adb logcat | grep -E "FATAL|AndroidRuntime|Exception" + ``` + +2. **Clear app data**: + ```bash + adb shell pm clear app.timesafari.app + ``` + +3. **Reinstall clean**: + ```bash + adb uninstall app.timesafari.app + npm run clean:android + npm run build:android:debug:run + ``` + +### Build Failures + +**Symptom**: Build fails before APK is created + +**Solutions**: + +1. **Asset validation**: + ```bash + npm run assets:validate:android + ``` + +2. **Clean and rebuild**: + ```bash + npm run clean:android + npm run build:android:debug + ``` + +3. **Check Gradle**: + ```bash + cd android + ./gradlew clean --stacktrace + ./gradlew assembleDebug --stacktrace + ``` + +## Wireless Debugging (Optional) + +Once initial USB connection is established, you can switch to wireless: + +### Enable Wireless Debugging + +```bash +# 1. Connect via USB first +adb devices + +# 2. Enable TCP/IP mode on port 5555 +adb tcpip 5555 + +# 3. Find device IP (on device: Settings → About → IP address) +# Or: +adb shell ip addr show wlan0 + +# 4. Connect wirelessly (disconnect USB cable) +adb connect 192.168.1.XXX:5555 + +# 5. Verify +adb devices +``` + +### Reconnect After Reboot + +```bash +# Device IP may have changed - check it first +adb connect 192.168.1.XXX:5555 +``` + +### Return to USB Mode + +```bash +adb usb +``` + +## Best Practices + +### Development Workflow + +1. **Keep device connected during development** for quick iteration + +2. **Use test builds for most testing**: + ```bash + npm run build:android:test:run + ``` + This avoids local server configuration hassles. + +3. **Use Chrome DevTools** for JavaScript debugging - much easier than logcat + +4. **Test on multiple devices** if possible - different Android versions behave differently + +### Performance Testing + +Physical devices give you real-world performance insights that emulators can't: + +- **Battery consumption**: Monitor with Settings → Battery +- **Network conditions**: Test on slow/unstable Wi-Fi +- **Memory pressure**: Test with many apps open +- **Touch responsiveness**: Actual finger input vs mouse clicks + +### Before Release Testing + +Always test on physical devices before any release: + +1. Fresh install (not upgrade) +2. Upgrade from previous version +3. Test on lowest supported Android version +4. Test on both phone and tablet if applicable + +## Quick Reference + +### Essential Commands + +```bash +# Check connected devices +adb devices + +# Build and run (debug) +npm run build:android:debug:run + +# Build and run (test environment) +npm run build:android:test:run + +# Install existing APK +adb install -r android/app/build/outputs/apk/debug/app-debug.apk + +# Uninstall app +adb uninstall app.timesafari.app + +# Launch app +adb shell am start -n app.timesafari.app/app.timesafari.MainActivity + +# View logs +adb logcat | grep TimeSafari + +# Take screenshot +adb exec-out screencap -p > screenshot.png + +# Record screen +adb shell screenrecord /sdcard/demo.mp4 +# (Ctrl+C to stop, then pull file) +adb pull /sdcard/demo.mp4 +``` + +### Build Modes Quick Reference + +| Command | Environment | API Servers | +|---------|-------------|-------------| +| `npm run build:android:dev` | Development | Local (your IP:3000) | +| `npm run build:android:test` | Test | test-api.endorser.ch | +| `npm run build:android:prod` | Production | api.endorser.ch | + +## Conclusion + +Physical device testing is essential for: +- ✅ Real-world performance validation +- ✅ Touch and gesture testing +- ✅ Camera and hardware feature testing +- ✅ Network condition testing +- ✅ Battery and resource usage analysis + +For emulator-based testing (useful for quick iteration), see [Android Emulator Deployment Guide](android-emulator-deployment-guide.md). + +For questions or additional troubleshooting, refer to the main [BUILDING.md](../BUILDING.md) documentation.