12 KiB
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 (
emulatorcommand) - 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:
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 (LTS), or on macOS:
brew install node.
- Install from nodejs.org (LTS), or on macOS:
-
Java (JDK 11+)
- macOS:
brew install openjdk@17and 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 / Oracle JDK and ensure
javaandjavacare on your PATH.
- macOS:
-
Android SDK (without Android Studio)
-
Download the Command-line tools only package for your OS.
-
Create an SDK directory, e.g.
mkdir -p ~/android-sdkand extract the zip so that you have~/android-sdk/cmdline-tools/latest/(thebinfolder withsdkmanagerandavdmanagermust be insidecmdline-tools/latest/). -
Set environment variables (add to
~/.zshrcor~/.bashrc):export ANDROID_HOME=$HOME/android-sdk export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator -
Install required SDK packages (accept licenses when prompted):
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"
- Apple Silicon (M1/M2/M3, aarch64):
-
Create at least one AVD (use the same image type you installed):
Apple Silicon:
avdmanager create avd -n Pixel8_API35 -k "system-images;android-35;google_apis;arm64-v8a" -d "pixel_8"Intel / x86_64:
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 useadb wait-for-devicebefore building/installing the app. -
-
Gradle
The project uses the Gradle Wrapper (gradlew) inside the app’sandroiddirectory. 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
# List available Android Virtual Devices (AVDs)
emulator -list-avds
# Example output:
# Pixel8_API35
2. Start the Emulator
# 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
# 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
# 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)
# 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
# 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 appadb install -r- Replace existing appadb install -t- Allow test APKs
7. Launch the App
# 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
# 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)
# 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
# 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
# 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)
# 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
# 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:
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
# Check ADB connection
adb devices
# Restart ADB server
adb kill-server
adb start-server
# Check ADB version
adb version
APK Installation Fails
# 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
# Clean build
cd android && ./gradlew clean
# Rebuild
./gradlew :app:assembleDebug
# Check Gradle daemon
./gradlew --status
Performance Optimization
Emulator Performance
# 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
# 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:
# 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
# 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
# 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
- Click "Test Plugin" - Tests the mock plugin implementation
- Click "Configure Plugin" - Tests plugin configuration
- Click "Check Status" - Tests plugin status retrieval
- Monitor logs - Check for any errors or issues
Development Workflow
- Make changes - Edit plugin code or test app
- Rebuild - Run the build commands
- Reinstall - Install updated APK
- Test - Launch and test functionality
- Iterate - Repeat as needed
This method provides a complete standalone Android development environment without requiring Android Studio! 🎉