From 35047a642c936796db9a67f81a42ad515eb8e7f1 Mon Sep 17 00:00:00 2001 From: Petr Korolev Date: Sat, 10 Jan 2026 16:22:18 -0500 Subject: [PATCH 1/3] Enhance MobileAppWizard documentation and scripts for better user guidance. Updated build commands to use npm scripts with preflight checks for iOS and Android. Added detailed prerequisites for development builds and introduced preflight check scripts for Android environment readiness. --- .../frontend/src/wizards/MobileAppWizard.tsx | 39 +++- ushadow/mobile/package-lock.json | 1 + ushadow/mobile/package.json | 6 +- ushadow/mobile/scripts/preflight-android.sh | 220 ++++++++++++++++++ 4 files changed, 255 insertions(+), 11 deletions(-) create mode 100755 ushadow/mobile/scripts/preflight-android.sh diff --git a/ushadow/frontend/src/wizards/MobileAppWizard.tsx b/ushadow/frontend/src/wizards/MobileAppWizard.tsx index bee7911d..5b42536a 100644 --- a/ushadow/frontend/src/wizards/MobileAppWizard.tsx +++ b/ushadow/frontend/src/wizards/MobileAppWizard.tsx @@ -216,16 +216,19 @@ export default function MobileAppWizard() {

- Full features including Bluetooth OMI device support. Requires a Mac for iOS or Android Studio for Android. + Full features including Bluetooth OMI device support. The build scripts automatically check prerequisites and provide helpful error messages.

# Install dependencies
cd ushadow/mobile && npm install
-
# Build and run on device
-
npx expo run:ios
-
# or
-
npx expo run:android
+
# iOS (Mac only - auto-boots simulator)
+
npm run ios
+
# Android (any platform)
+
npm run android
+

+ Scripts auto-check for required tools and will guide you if anything is missing. +

{/* Option 2: Android APK */} @@ -291,10 +294,28 @@ export default function MobileAppWizard() { {/* Prerequisites Note */} -
-

- Prerequisites: Node.js 18+, and for development builds: Xcode (iOS) or Android Studio (Android). - See ushadow/mobile/README.md for detailed setup. +

+

Prerequisites for Development Builds:

+
+
+
iOS (Mac only)
+
    +
  • Xcode (from App Store)
  • +
  • iOS Simulator runtime
  • +
  • Xcode Command Line Tools
  • +
+
+
+
Android (any platform)
+
    +
  • Java JDK 17 (brew install openjdk@17)
  • +
  • Android Studio + SDK
  • +
  • Emulator or USB device
  • +
+
+
+

+ Run npm run ios or npm run android to see exactly what's missing.

diff --git a/ushadow/mobile/package-lock.json b/ushadow/mobile/package-lock.json index 3585ac2a..3f79d816 100644 --- a/ushadow/mobile/package-lock.json +++ b/ushadow/mobile/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "ushadow", "version": "1.0.0", + "hasInstallScript": true, "dependencies": { "@expo/vector-icons": "^15.0.3", "@react-native-async-storage/async-storage": "^2.2.0", diff --git a/ushadow/mobile/package.json b/ushadow/mobile/package.json index 0d41a338..9ab312c2 100644 --- a/ushadow/mobile/package.json +++ b/ushadow/mobile/package.json @@ -5,8 +5,10 @@ "scripts": { "start": "expo start", "reset-project": "node ./scripts/reset-project.js", - "android": "expo run:android", - "ios": "expo run:ios", + "android": "./scripts/preflight-android.sh && expo run:android", + "android:skip-preflight": "expo run:android", + "ios": "./scripts/preflight-ios.sh && expo run:ios", + "ios:skip-preflight": "expo run:ios", "web": "expo start --web", "lint": "expo lint", "postinstall": "patch-package" diff --git a/ushadow/mobile/scripts/preflight-android.sh b/ushadow/mobile/scripts/preflight-android.sh new file mode 100755 index 00000000..6830c5bc --- /dev/null +++ b/ushadow/mobile/scripts/preflight-android.sh @@ -0,0 +1,220 @@ +#!/bin/bash +# Android Preflight Check Script +# Ensures Android development environment is ready before running expo run:android +# Note: We don't use 'set -e' here to ensure error messages are displayed properly + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +echo -e "${BLUE}╔════════════════════════════════════════════════════════════════╗${NC}" +echo -e "${BLUE}║ Android Development Environment Check ║${NC}" +echo -e "${BLUE}║ Tip: Always use 'npm run android' to get these checks ║${NC}" +echo -e "${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}" +echo "" + +# Check for Java - need to verify it actually works, not just that the command exists +# Android builds require Java because the Android build system (Gradle) runs on the JVM +JAVA_CHECK=$(java -version 2>&1) +if echo "$JAVA_CHECK" | grep -qi "Unable to locate\|not found\|No Java\|error"; then + echo -e "${RED}╔════════════════════════════════════════════════════════════════╗${NC}" + echo -e "${RED}║ ERROR: Java JDK is not installed ║${NC}" + echo -e "${RED}╚════════════════════════════════════════════════════════════════╝${NC}" + echo "" + echo -e "${YELLOW}Why is Java needed?${NC}" + echo " Android apps are built using Gradle, which requires Java to run." + echo " React Native/Expo uses Gradle under the hood to compile your app." + echo "" + echo -e "${YELLOW}How to fix:${NC}" + echo "" + if [[ "$OSTYPE" == "darwin"* ]]; then + echo -e "${GREEN}Option 1 - Homebrew (recommended):${NC}" + echo "" + echo " Step 1: Install OpenJDK 17" + echo -e " ${BLUE}brew install openjdk@17${NC}" + echo "" + echo " Step 2: Link it so the system can find it" + echo -e " ${BLUE}sudo ln -sfn \$(brew --prefix)/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk${NC}" + echo "" + echo " Step 3: Restart your terminal, then run:" + echo -e " ${BLUE}npm run android${NC}" + echo "" + echo -e "${GREEN}Option 2 - Download installer:${NC}" + echo " https://adoptium.net/temurin/releases/?version=17" + echo " Download the .pkg file for macOS and run the installer." + else + echo -e "${GREEN}Ubuntu/Debian:${NC}" + echo -e " ${BLUE}sudo apt install openjdk-17-jdk${NC}" + echo "" + echo -e "${GREEN}Or download from:${NC}" + echo " https://adoptium.net/temurin/releases/?version=17" + fi + echo "" + echo -e "${YELLOW}After installing Java, restart your terminal and run: npm run android${NC}" + echo "" + exit 1 +fi + +# Check Java version +JAVA_VERSION=$(echo "$JAVA_CHECK" | head -1 | cut -d'"' -f2 | cut -d'.' -f1 2>/dev/null || echo "0") +echo -e "${GREEN}Java found: $(echo "$JAVA_CHECK" | head -1)${NC}" + +if [ "$JAVA_VERSION" -lt 11 ] 2>/dev/null; then + echo -e "${YELLOW}Warning: Java version $JAVA_VERSION detected. Java 17 is recommended for React Native.${NC}" +fi + +# Check for ANDROID_HOME or ANDROID_SDK_ROOT +if [ -z "$ANDROID_HOME" ] && [ -z "$ANDROID_SDK_ROOT" ]; then + # Try common locations + if [ -d "$HOME/Library/Android/sdk" ]; then + export ANDROID_HOME="$HOME/Library/Android/sdk" + echo -e "${YELLOW}ANDROID_HOME not set, using: $ANDROID_HOME${NC}" + elif [ -d "$HOME/Android/Sdk" ]; then + export ANDROID_HOME="$HOME/Android/Sdk" + echo -e "${YELLOW}ANDROID_HOME not set, using: $ANDROID_HOME${NC}" + else + echo -e "${RED}╔════════════════════════════════════════════════════════════════╗${NC}" + echo -e "${RED}║ ERROR: Android SDK not found ║${NC}" + echo -e "${RED}╚════════════════════════════════════════════════════════════════╝${NC}" + echo "" + echo -e "${YELLOW}Why is the Android SDK needed?${NC}" + echo " The Android SDK contains tools to compile and package your app" + echo " for Android devices. It's installed alongside Android Studio." + echo "" + echo -e "${YELLOW}How to fix:${NC}" + echo "" + echo -e "${GREEN}Step 1: Install Android Studio${NC}" + echo " Download from: https://developer.android.com/studio" + echo " Run the installer and complete the setup wizard." + echo "" + echo -e "${GREEN}Step 2: Add environment variables${NC}" + echo " Add these lines to your shell profile (~/.zshrc or ~/.bashrc):" + echo "" + if [[ "$OSTYPE" == "darwin"* ]]; then + echo -e " ${BLUE}export ANDROID_HOME=\$HOME/Library/Android/sdk${NC}" + else + echo -e " ${BLUE}export ANDROID_HOME=\$HOME/Android/Sdk${NC}" + fi + echo -e " ${BLUE}export PATH=\$PATH:\$ANDROID_HOME/emulator${NC}" + echo -e " ${BLUE}export PATH=\$PATH:\$ANDROID_HOME/platform-tools${NC}" + echo "" + echo -e "${GREEN}Step 3: Reload your shell${NC}" + echo -e " ${BLUE}source ~/.zshrc${NC} (or restart your terminal)" + echo "" + echo -e "${YELLOW}Then run: npm run android${NC}" + echo "" + exit 1 + fi +else + ANDROID_HOME="${ANDROID_HOME:-$ANDROID_SDK_ROOT}" +fi + +echo -e "${GREEN}Android SDK: $ANDROID_HOME${NC}" + +# Check for platform-tools (adb) +if [ ! -f "$ANDROID_HOME/platform-tools/adb" ]; then + echo -e "${RED}╔════════════════════════════════════════════════════════════════╗${NC}" + echo -e "${RED}║ ERROR: Android platform-tools (adb) not found ║${NC}" + echo -e "${RED}╚════════════════════════════════════════════════════════════════╝${NC}" + echo "" + echo -e "${YELLOW}Why are platform-tools needed?${NC}" + echo " Platform-tools include 'adb' (Android Debug Bridge), which is used" + echo " to communicate with your Android device or emulator." + echo "" + echo -e "${YELLOW}How to fix:${NC}" + echo " 1. Open Android Studio" + echo " 2. Go to Tools > SDK Manager > SDK Tools tab" + echo " 3. Check 'Android SDK Platform-Tools' and click Apply" + echo "" + exit 1 +fi + +# Add platform-tools to PATH if not already there +export PATH="$PATH:$ANDROID_HOME/platform-tools" + +# Check for connected devices or running emulators +echo "" +echo "Checking for Android devices..." + +DEVICES=$("$ANDROID_HOME/platform-tools/adb" devices 2>/dev/null | grep -v "List" | grep -v "^$" || echo "") + +if [ -z "$DEVICES" ]; then + echo -e "${YELLOW}No Android devices connected${NC}" + echo "" + + # Check if any emulator is available + if [ -d "$ANDROID_HOME/emulator" ] && [ -f "$ANDROID_HOME/emulator/emulator" ]; then + AVDS=$("$ANDROID_HOME/emulator/emulator" -list-avds 2>/dev/null || echo "") + + if [ -n "$AVDS" ]; then + echo "Available emulators:" + echo "$AVDS" | while read avd; do echo " - $avd"; done + echo "" + + # Try to start the first available emulator + FIRST_AVD=$(echo "$AVDS" | head -1) + echo -e "${BLUE}Starting emulator: $FIRST_AVD${NC}" + "$ANDROID_HOME/emulator/emulator" -avd "$FIRST_AVD" -no-snapshot-load & + + echo "Waiting for emulator to boot..." + # Wait for device to be ready (max 60 seconds) + for i in {1..30}; do + sleep 2 + BOOT_STATUS=$("$ANDROID_HOME/platform-tools/adb" shell getprop sys.boot_completed 2>/dev/null || echo "") + if [ "$BOOT_STATUS" = "1" ]; then + echo -e "${GREEN}Emulator is ready!${NC}" + break + fi + echo " Still booting... ($i/30)" + done + else + echo -e "${RED}╔════════════════════════════════════════════════════════════════╗${NC}" + echo -e "${RED}║ ERROR: No Android emulators configured ║${NC}" + echo -e "${RED}╚════════════════════════════════════════════════════════════════╝${NC}" + echo "" + echo -e "${YELLOW}You need either an emulator or a physical device to run the app.${NC}" + echo "" + echo -e "${GREEN}Option 1 - Create an emulator:${NC}" + echo " 1. Open Android Studio" + echo " 2. Go to Tools > Device Manager" + echo " 3. Click 'Create Device' and follow the wizard" + echo " 4. Download a system image when prompted (e.g., API 34)" + echo "" + echo -e "${GREEN}Option 2 - Connect a physical device via USB:${NC}" + echo " 1. On your phone: Settings > About Phone" + echo " Tap 'Build Number' 7 times to enable Developer Options" + echo " 2. Go to Settings > Developer Options" + echo " Enable 'USB Debugging'" + echo " 3. Connect your phone via USB cable" + echo " 4. Accept the debugging prompt on your phone" + echo "" + exit 1 + fi + else + echo -e "${RED}╔════════════════════════════════════════════════════════════════╗${NC}" + echo -e "${RED}║ ERROR: Android Emulator not installed ║${NC}" + echo -e "${RED}╚════════════════════════════════════════════════════════════════╝${NC}" + echo "" + echo -e "${YELLOW}How to fix:${NC}" + echo " 1. Open Android Studio" + echo " 2. Go to Tools > SDK Manager > SDK Tools tab" + echo " 3. Check 'Android Emulator' and click Apply" + echo " 4. Then go to Tools > Device Manager to create a virtual device" + echo "" + echo "Or connect a physical Android device via USB (see above)" + exit 1 + fi +else + echo -e "${GREEN}Connected devices:${NC}" + echo "$DEVICES" | while read device; do + if [ -n "$device" ]; then + echo " - $device" + fi + done +fi + +echo "" +echo -e "${GREEN}=== Android environment ready! ===${NC}" +echo "" From 9f3eb26b59e6d5ec872571736221eddb0ad2008f Mon Sep 17 00:00:00 2001 From: Petr Korolev Date: Sat, 10 Jan 2026 16:40:28 -0500 Subject: [PATCH 2/3] Update README.md with troubleshooting steps for Android SDK location issues, including environment variable setup and local.properties configuration. --- ushadow/mobile/README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/ushadow/mobile/README.md b/ushadow/mobile/README.md index b1ed8e86..dcce72af 100644 --- a/ushadow/mobile/README.md +++ b/ushadow/mobile/README.md @@ -163,6 +163,36 @@ eas device:create - Verify URLs don't have trailing slashes - Try both `ws://` and `wss://` for stream URL +### Android: "SDK location not found" +When running `npx expo run:android`, you may see: +``` +SDK location not found. Define a valid SDK location with an ANDROID_HOME +environment variable or by setting the sdk.dir path in your project's +local.properties file +``` + +**Cause:** The Android build system (Gradle) can't find your Android SDK installation. + +**Fix:** Create `android/local.properties` with your SDK path: +```bash +# On macOS (typical Android Studio installation): +echo "sdk.dir=$HOME/Library/Android/sdk" > android/local.properties + +# On Linux: +echo "sdk.dir=$HOME/Android/Sdk" > android/local.properties + +# On Windows (Git Bash): +echo "sdk.dir=C:\\Users\\YourUsername\\AppData\\Local\\Android\\Sdk" > android/local.properties +``` + +**Permanent fix:** Add to your shell profile (`~/.zshrc` or `~/.bashrc`): +```bash +export ANDROID_HOME=$HOME/Library/Android/sdk # macOS +export PATH=$PATH:$ANDROID_HOME/platform-tools +``` + +**Note:** `local.properties` is gitignored because it contains machine-specific paths. + ### Build fails ```bash # Clean and rebuild From 8fa8d1612b653fe59d24d44eb7d8c717cd92eef9 Mon Sep 17 00:00:00 2001 From: Petr Korolev Date: Sat, 10 Jan 2026 17:42:56 -0500 Subject: [PATCH 3/3] Enhance README.md with detailed instructions for running on a physical iPhone, including prerequisites and device connection steps. --- ushadow/mobile/README.md | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/ushadow/mobile/README.md b/ushadow/mobile/README.md index dcce72af..c3a035d7 100644 --- a/ushadow/mobile/README.md +++ b/ushadow/mobile/README.md @@ -83,15 +83,45 @@ eas build --profile preview --platform android #### Development (Recommended) ```bash -# Connect your iOS device via USB -# Trust your computer on the device - npm install npx expo prebuild --platform ios cd ios && pod install && cd .. npx expo run:ios --device ``` +#### Running on Physical iPhone + +To run on a physical iPhone instead of the simulator, use the `--device` flag: + +```bash +npx expo run:ios --device +``` + +This will show a list of connected devices. You can also specify the device name directly: + +```bash +npx expo run:ios --device "iPhone Air" +``` + +**Prerequisites for physical device:** + +1. **Connect via USB** - Connect your iPhone to your Mac with a cable + +2. **Trust the computer** - On your iPhone, tap "Trust" when prompted with "Trust This Computer?" + +3. **Enable Developer Mode** (iOS 16+) - Go to **Settings → Privacy & Security → Developer Mode** and enable it. Your device will restart. + +4. **Apple Developer account** - Sign into Xcode with your Apple ID: + - Open Xcode → Settings → Accounts → Add your Apple ID + +5. **Code signing** - First build requires signing setup: + ```bash + open ios/*.xcworkspace + ``` + In Xcode: Select your project → Signing & Capabilities → Select your Team + +After initial setup, subsequent builds with `npx expo run:ios --device` will work automatically. + #### Distribution via TestFlight (Easiest for iOS) 1. Apple Developer account ($99/year required) 2. Build with EAS: