Files
daily-notification-plugin/doc/testing/EMULATOR_GUIDE.md

451 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Running Android App in Standalone Emulator (Without Android Studio)
**Author**: Matthew Raymer
**Last Updated**: 2026-02-05
**Version**: 1.1.0
## Overview
This guide demonstrates how to run the DailyNotification plugin test app in a standalone Android emulator without using Android Studio. This method is useful for development, CI/CD pipelines, and resource-constrained environments.
## Prerequisites
### Required Software
- **Android SDK** with command line tools
- **Android Emulator** (`emulator` command)
- **ADB** (Android Debug Bridge)
- **Gradle** (via Gradle Wrapper)
- **Node.js** and **npm** (for TypeScript compilation)
### System Requirements
- **RAM**: 4GB minimum, 8GB recommended
- **Storage**: 2GB free space for emulator
- **OS**: Linux, macOS, or Windows with WSL
## Checking and Installing Prerequisites
### How to check
Run these in a terminal. If a command is missing or a check fails, use the install steps below.
| Requirement | How to check |
|------------------|--------------|
| **Node.js** | `node --version` (v14+ recommended; test app may require 20+) |
| **npm** | `npm --version` |
| **Java** | `java -version` (Java 11+; build scripts expect 11+) |
| **ANDROID_HOME** | `echo $ANDROID_HOME` (must be set to your Android SDK root) |
| **adb** | `adb version` (must be on PATH; usually `$ANDROID_HOME/platform-tools/adb`) |
| **emulator** | `emulator -version` (must be on PATH; usually `$ANDROID_HOME/emulator/emulator`) |
| **At least one AVD** | `emulator -list-avds` (must list at least one device name) |
**Project script:** From the repo root you can run:
```bash
node scripts/check-environment.js
```
This checks Node, npm, Java, and `ANDROID_HOME`. It does **not** check `adb`, `emulator`, or AVDs—verify those manually as above.
### How to install
- **Node.js and npm**
- Install from [nodejs.org](https://nodejs.org/) (LTS), or on macOS: `brew install node`.
- **Java (JDK 11+)**
- macOS: `brew install openjdk@17` and follow the caveats to link (e.g. `sudo ln -sfn $(brew --prefix)/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk`).
- Or install [Eclipse Temurin](https://adoptium.net/) / [Oracle JDK](https://www.oracle.com/java/technologies/downloads/) and ensure `java` and `javac` are on your PATH.
- **Android SDK (without Android Studio)**
1. Download the [Command-line tools only](https://developer.android.com/studio#command-tools) package for your OS.
2. Create an SDK directory, e.g. `mkdir -p ~/android-sdk` and extract the zip so that you have `~/android-sdk/cmdline-tools/latest/` (the `bin` folder with `sdkmanager` and `avdmanager` must be inside `cmdline-tools/latest/`).
3. Set environment variables (add to `~/.zshrc` or `~/.bashrc`):
```bash
export ANDROID_HOME=$HOME/android-sdk
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator
```
4. Install required SDK packages (accept licenses when prompted):
```bash
sdkmanager "platform-tools"
sdkmanager "emulator"
sdkmanager "platforms;android-35"
sdkmanager "build-tools;35.0.0"
```
Install a system image that matches your host CPU:
- **Apple Silicon (M1/M2/M3, aarch64):** `sdkmanager "system-images;android-35;google_apis;arm64-v8a"`
- **Intel Mac / Windows / Linux (x86_64):** `sdkmanager "system-images;android-35;google_apis;x86_64"`
5. Create at least one AVD (use the same image type you installed):
**Apple Silicon:**
```bash
avdmanager create avd -n Pixel8_API35 -k "system-images;android-35;google_apis;arm64-v8a" -d "pixel_8"
```
**Intel / x86_64:**
```bash
avdmanager create avd -n Pixel8_API35 -k "system-images;android-35;google_apis;x86_64" -d "pixel_8"
```
Then start the emulator with: `emulator -avd Pixel8_API35 -no-snapshot-load &` and use `adb wait-for-device` before building/installing the app.
- **Gradle**
The project uses the Gradle Wrapper (`gradlew`) inside the apps `android` directory. No separate Gradle install is needed.
After installing, run the checks again to confirm `adb`, `emulator`, and `emulator -list-avds` work.
## Step-by-Step Process
### 1. Check Available Emulators
```bash
# List available Android Virtual Devices (AVDs)
emulator -list-avds
# Example output:
# Pixel8_API35
```
### 2. Start the Emulator
```bash
# Start emulator in background (recommended)
emulator -avd Pixel8_API35 -no-snapshot-load &
# Alternative: Start in foreground
emulator -avd Pixel8_API35
```
**Flags Explained:**
- `-avd Pixel8_API35` - Specifies the AVD to use
- `-no-snapshot-load` - Forces fresh boot (recommended for testing)
- `&` - Runs in background (optional)
### 3. Wait for Emulator to Boot
```bash
# Wait for emulator to be ready
adb wait-for-device
# Verify emulator is running
adb devices
# Example output:
# List of devices attached
# emulator-5554 device
```
### 4. Build the Plugin and Test App
```bash
# Navigate to project directory
cd /path/to/daily-notification-plugin
# Build TypeScript and native code
./scripts/build-native.sh --platform android
```
**What this does:**
- Compiles TypeScript to JavaScript
- Builds Android native code
- Creates plugin AAR files
- Builds test app APK
### 5. Build Debug APK (Required for Installation)
```bash
# Navigate to Android directory
cd android
# Build debug version (includes debug signing)
./gradlew :app:assembleDebug
```
**Why Debug APK:**
- **Debug signing** - Automatically signed for installation
- **No certificates needed** - Uses default debug keystore
- **Faster builds** - No optimization, faster compilation
### 6. Install APK on Emulator
```bash
# Install the debug APK
adb install app/build/outputs/apk/debug/app-debug.apk
# Alternative: Install with replacement
adb install -r app/build/outputs/apk/debug/app-debug.apk
```
**Installation Options:**
- `adb install` - Install new app
- `adb install -r` - Replace existing app
- `adb install -t` - Allow test APKs
### 7. Launch the App
```bash
# Launch the app
adb shell am start -n org.timesafari.dailynotification/.MainActivity
# Alternative: Launch with specific intent
adb shell am start -a android.intent.action.MAIN -n org.timesafari.dailynotification/.MainActivity
```
### 8. Monitor App Logs
```bash
# View all logs
adb logcat
# Filter for specific tags
adb logcat -s "Capacitor" "DailyNotification" "Console"
# View logs for specific process
adb logcat --pid=<PID>
# Clear logs and view new ones
adb logcat -c && adb logcat
```
## Complete Command Sequence
### Quick Start (Copy-Paste Ready)
```bash
# 1. Start emulator
emulator -avd Pixel8_API35 -no-snapshot-load &
# 2. Wait for emulator
adb wait-for-device
# 3. Build everything
./scripts/build-native.sh --platform android
# 4. Build debug APK
cd android && ./gradlew :app:assembleDebug
# 5. Install APK
adb install app/build/outputs/apk/debug/app-debug.apk
# 6. Launch app
adb shell am start -n org.timesafari.dailynotification/.MainActivity
# 7. Monitor logs
adb logcat -s "Capacitor" "DailyNotification" "Console"
```
## Alternative Methods
### Method 1: Using Capacitor CLI
```bash
# Build and run in one command
npx cap run android
# This will:
# - Build the plugin
# - Sync web assets
# - Build and install APK
# - Launch the app
```
### Method 2: Direct Gradle Commands
```bash
# Build and install directly
cd android
./gradlew :app:assembleDebug
adb install app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n org.timesafari.dailynotification/.MainActivity
```
### Method 3: Using Monkey (Alternative Launch)
```bash
# Install and launch with Monkey
adb install app/build/outputs/apk/debug/app-debug.apk
adb shell monkey -p org.timesafari.dailynotification -c android.intent.category.LAUNCHER 1
```
## Troubleshooting
### Common Issues
#### Emulator Won't Start
```bash
# Check available AVDs
emulator -list-avds
# Check emulator process
ps aux | grep emulator
# Kill existing emulator
pkill -f emulator
# Start with verbose logging
emulator -avd Pixel8_API35 -verbose
```
#### "x86_64 is not supported by the QEMU2 emulator on aarch64 host"
On Apple Silicon (M1/M2/M3), the emulator cannot run x86_64 system images. Use an ARM64 image and AVD instead:
```bash
sdkmanager "system-images;android-35;google_apis;arm64-v8a"
avdmanager delete avd -n Pixel8_API35 # if you already created an x86_64 AVD
avdmanager create avd -n Pixel8_API35 -k "system-images;android-35;google_apis;arm64-v8a" -d "pixel_8"
emulator -avd Pixel8_API35 -no-snapshot-load
```
#### ADB Connection Issues
```bash
# Check ADB connection
adb devices
# Restart ADB server
adb kill-server
adb start-server
# Check ADB version
adb version
```
#### APK Installation Fails
```bash
# Check if app is already installed
adb shell pm list packages | grep timesafari
# Uninstall existing app
adb uninstall org.timesafari.dailynotification
# Install with force
adb install -r -t app/build/outputs/apk/debug/app-debug.apk
```
#### Build Failures
```bash
# Clean build
cd android && ./gradlew clean
# Rebuild
./gradlew :app:assembleDebug
# Check Gradle daemon
./gradlew --status
```
### Performance Optimization
#### Emulator Performance
```bash
# Start with hardware acceleration
emulator -avd Pixel8_API35 -accel on
# Start with specific RAM allocation
emulator -avd Pixel8_API35 -memory 2048
# Start with GPU acceleration
emulator -avd Pixel8_API35 -gpu host
```
#### Build Performance
```bash
# Enable Gradle daemon
echo "org.gradle.daemon=true" >> ~/.gradle/gradle.properties
# Increase memory
echo "org.gradle.jvmargs=-Xmx4g" >> ~/.gradle/gradle.properties
# Enable parallel builds
echo "org.gradle.parallel=true" >> ~/.gradle/gradle.properties
```
## Expected Results
### Successful App Launch
When the app launches successfully, you should see:
```bash
# ADB output
Starting: Intent { cmp=org.timesafari.dailynotification/.MainActivity }
# Logcat output
D Capacitor: Starting BridgeActivity
D Capacitor: Registering plugin instance: CapacitorCookies
D Capacitor: Registering plugin instance: WebView
D Capacitor: Registering plugin instance: CapacitorHttp
D Capacitor: Loading app at https://localhost
D Capacitor: App started
D Capacitor: App resumed
I Capacitor/Console: Script loading...
I Capacitor/Console: Creating mock DailyNotification plugin...
I Capacitor/Console: Functions attached to window: [object Object]
```
### App Interface
The app should display:
- **Title**: "🔔 DailyNotification Plugin Test"
- **Three buttons**: "Test Plugin", "Configure Plugin", "Check Status"
- **Status area**: Shows test results and plugin status
## Benefits of Standalone Approach
### Advantages
- ✅ **No Android Studio** - Pure command line workflow
- ✅ **Faster startup** - No IDE overhead
- ✅ **CI/CD friendly** - Works in automated environments
- ✅ **Resource efficient** - Lower memory usage
- ✅ **Scriptable** - Can be automated
- ✅ **Remote development** - Works over SSH
### Use Cases
- **Development** - Quick testing and iteration
- **CI/CD pipelines** - Automated testing
- **Remote development** - SSH-based development
- **Resource-constrained environments** - Low-spec machines
- **Team environments** - Shared development servers
## Integration with Development Workflow
### Daily Development
```bash
# Quick test cycle
./scripts/build-native.sh --platform android
cd android && ./gradlew :app:assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n org.timesafari.dailynotification/.MainActivity
```
### Automated Testing
```bash
# CI/CD pipeline
emulator -avd Pixel8_API35 -no-snapshot-load &
adb wait-for-device
./scripts/build-native.sh --platform android
cd android && ./gradlew :app:assembleDebug
adb install app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n org.timesafari.dailynotification/.MainActivity
# Run tests...
```
## Next Steps
### Testing the App
1. **Click "Test Plugin"** - Tests the mock plugin implementation
2. **Click "Configure Plugin"** - Tests plugin configuration
3. **Click "Check Status"** - Tests plugin status retrieval
4. **Monitor logs** - Check for any errors or issues
### Development Workflow
1. **Make changes** - Edit plugin code or test app
2. **Rebuild** - Run the build commands
3. **Reinstall** - Install updated APK
4. **Test** - Launch and test functionality
5. **Iterate** - Repeat as needed
---
**This method provides a complete standalone Android development environment without requiring Android Studio!** 🎉