Add comprehensive guide for building and testing TimeSafari on physical Android devices, covering device setup, USB debugging, network configuration for local development servers, and troubleshooting. - Create doc/android-physical-device-guide.md with full instructions - Update BUILDING.md to reference the new guide in two places
12 KiB
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
-
Android SDK Platform Tools (includes
adb)# macOS (Homebrew) brew install android-platform-tools # Or via Android SDK Manager sdkmanager "platform-tools" -
Node.js 18+ and npm
-
Java Development Kit (JDK) 17+
# macOS (Homebrew) brew install openjdk@17 # Verify installation java -version
Environment Setup
Add to your shell configuration (~/.zshrc or ~/.bashrc):
# 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:
source ~/.zshrc # or source ~/.bashrc
Verify installation:
adb version
Device Setup
Step 1: Enable Developer Options
Developer Options is hidden by default on Android devices. To enable it:
- Open Settings on your Android device
- Scroll down and tap About phone (or About device)
- Find Build number and tap it 7 times rapidly
- You'll see a message: "You are now a developer!"
- Go back to Settings - Developer options now appears
Step 2: Enable USB Debugging
- Go to Settings → Developer options
- Enable USB debugging (toggle it ON)
- 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
- Connect your Android device to your computer via USB cable
- On your device, you'll see a prompt: "Allow USB debugging?"
- Check "Always allow from this computer" (recommended)
- Tap Allow
Step 4: Verify Connection
# 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.2to reach the host machine - Physical devices need your computer's actual LAN IP address
Step 1: Find Your Computer's IP Address
# 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:
# .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:
# 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:
# Build with test API servers (no local server needed)
npm run build:android:test
Building and Deploying
Quick Start (Recommended)
# 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
# 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
# Install (replace existing if present)
adb install -r android/app/build/outputs/apk/debug/app-debug.apk
Step 3: Launch the App
# Start the app
adb shell am start -n app.timesafari.app/app.timesafari.MainActivity
One-Line Deploy Commands
# 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
# 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)
- Open Chrome on your computer
- Navigate to
chrome://inspect - Your device should appear under "Remote Target"
- 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
# 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:
-
Check USB cable: Some cables are charge-only. Use a data-capable USB cable.
-
Revoke USB debugging authorizations (on device):
- Settings → Developer options → Revoke USB debugging authorizations
- Reconnect and re-authorize
-
Restart ADB server:
adb kill-server adb start-server adb devices -
Try different USB port: Some USB hubs don't work well with ADB.
-
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:
-
Verify IP address:
# Make sure you have the right IP ipconfig getifaddr en0 # macOS -
Check firewall: Temporarily disable firewall or add exception for port 3000
-
Test connectivity from device:
- Open Chrome on your Android device
- Navigate to
http://YOUR_IP:3000 - Should see your API response
-
Verify server is listening on all interfaces:
# Should show 0.0.0.0:3000, not 127.0.0.1:3000 lsof -i :3000 -
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:
-
INSTALL_FAILED_UPDATE_INCOMPATIBLE:
# Uninstall existing app first adb uninstall app.timesafari.app adb install android/app/build/outputs/apk/debug/app-debug.apk -
INSTALL_FAILED_INSUFFICIENT_STORAGE:
- Free up space on the device
- Or install to SD card if available
-
INSTALL_FAILED_USER_RESTRICTED:
- Enable "Install via USB" in Developer options
- On some devices: Settings → Security → Unknown sources
-
Signature mismatch:
# 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:
-
Check crash logs:
adb logcat | grep -E "FATAL|AndroidRuntime|Exception" -
Clear app data:
adb shell pm clear app.timesafari.app -
Reinstall clean:
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:
-
Asset validation:
npm run assets:validate:android -
Clean and rebuild:
npm run clean:android npm run build:android:debug -
Check Gradle:
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
# 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
# Device IP may have changed - check it first
adb connect 192.168.1.XXX:5555
Return to USB Mode
adb usb
Best Practices
Development Workflow
-
Keep device connected during development for quick iteration
-
Use test builds for most testing:
npm run build:android:test:runThis avoids local server configuration hassles.
-
Use Chrome DevTools for JavaScript debugging - much easier than logcat
-
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:
- Fresh install (not upgrade)
- Upgrade from previous version
- Test on lowest supported Android version
- Test on both phone and tablet if applicable
Quick Reference
Essential Commands
# 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.
For questions or additional troubleshooting, refer to the main BUILDING.md documentation.