Files
alfred-mobile/BUILD_RELEASE.md
jknapp 6d4ae2e5c3 Initial commit: Alfred Mobile - AI Assistant Android App
- OAuth authentication via Authentik
- WebSocket connection to OpenClaw gateway
- Configurable gateway URL with first-run setup
- User preferences sync across devices
- Multi-user support with custom assistant names
- ElevenLabs TTS integration (local + remote)
- FCM push notifications for alarms
- Voice input via Google Speech API
- No hardcoded secrets or internal IPs in tracked files
2026-02-09 11:12:51 -08:00

8.0 KiB

Building Release APK

Guide for building and distributing the Alfred Mobile app for testing on multiple devices.

Prerequisites

  • Android SDK installed: ~/android-dev/android-sdk
  • JDK 17: ~/android-dev/jdk-17.0.2
  • Keystore for signing (or create new one)

Quick Build (Debug APK)

For testing on your own devices without Play Store distribution:

cd ~/.openclaw/workspace/alfred-mobile

# Build debug APK
JAVA_HOME=~/android-dev/jdk-17.0.2 \
ANDROID_HOME=~/android-dev/android-sdk \
./gradlew assembleDebug

# APK location:
ls -lh app/build/outputs/apk/debug/app-debug.apk

Install on device via ADB:

# Wireless ADB (if already paired)
~/android-dev/android-sdk/platform-tools/adb install -r app/build/outputs/apk/debug/app-debug.apk

# USB ADB (if connected via USB)
~/android-dev/android-sdk/platform-tools/adb devices
~/android-dev/android-sdk/platform-tools/adb install -r app/build/outputs/apk/debug/app-debug.apk

Transfer APK to another device:

# Copy to accessible location
cp app/build/outputs/apk/debug/app-debug.apk ~/app-debug.apk

# Transfer to phone via:
# - USB cable (file transfer)
# - Email attachment
# - Cloud storage (Dropbox, Google Drive)
# - Local HTTP server (python -m http.server)
# - ADB over network (if phone and computer on same WiFi)

Release APK (Signed)

For distribution outside development devices:

1. Create Keystore (One-time)

keytool -genkey -v \
  -keystore ~/alfred-mobile-release.keystore \
  -alias alfred-mobile \
  -keyalg RSA \
  -keysize 2048 \
  -validity 10000

# Enter password when prompted (save it!)
# Fill in organizational details

2. Create keystore.properties

cat > ~/.openclaw/workspace/alfred-mobile/keystore.properties << 'EOF'
storePassword=YOUR_KEYSTORE_PASSWORD
keyPassword=YOUR_KEY_PASSWORD
keyAlias=alfred-mobile
storeFile=/home/jknapp/alfred-mobile-release.keystore
EOF

3. Update build.gradle (if needed)

The app/build.gradle.kts should already have release signing config:

signingConfigs {
    create("release") {
        // Read from keystore.properties
        val keystorePropertiesFile = rootProject.file("keystore.properties")
        if (keystorePropertiesFile.exists()) {
            val keystoreProperties = Properties()
            keystoreProperties.load(FileInputStream(keystorePropertiesFile))
            
            storeFile = file(keystoreProperties["storeFile"] as String)
            storePassword = keystoreProperties["storePassword"] as String
            keyAlias = keystoreProperties["keyAlias"] as String
            keyPassword = keystoreProperties["keyPassword"] as String
        }
    }
}

buildTypes {
    release {
        isMinifyEnabled = true
        proguardFiles(/* ... */)
        signingConfig = signingConfigs.getByName("release")
    }
}

4. Build Release APK

cd ~/.openclaw/workspace/alfred-mobile

# Build signed release APK
JAVA_HOME=~/android-dev/jdk-17.0.2 \
ANDROID_HOME=~/android-dev/android-sdk \
./gradlew assembleRelease

# APK location:
ls -lh app/build/outputs/apk/release/app-release.apk

5. Verify Signature

# Check if APK is signed
~/android-dev/android-sdk/build-tools/*/apksigner verify \
  --print-certs \
  app/build/outputs/apk/release/app-release.apk

# Should show certificate details (not "unsigned")

Testing Cross-Device Alarm Dismissal

Setup

  1. Build APK (debug or release)
  2. Install on tablet:
    adb -s adb-R52R30ASB4Y-BIkpas install -r app-debug.apk
    
  3. Install on phone:
    • Transfer APK to phone
    • Enable "Install from unknown sources" in phone settings
    • Open APK file and install
    • OR use adb install if phone has ADB enabled

Testing Procedure

See CROSS_DEVICE_ALARMS.md for full testing procedure.

Quick test:

  1. Open Alfred app on both devices
  2. Authenticate on both (same account)
  3. Send test alarm:
    curl -X POST http://localhost:18790/api/notify \
      -H "Content-Type: application/json" \
      -d '{"notificationType":"alarm","title":"Cross-Device Test","message":"Testing sync","priority":"high","sound":true,"vibrate":true}'
    
  4. Verify alarm triggers on both devices
  5. Dismiss on ONE device
  6. Verify alarm stops on BOTH devices

Troubleshooting

"Unsigned APK" Error

  • Make sure keystore.properties exists and has correct paths
  • Verify keystore file exists at specified location
  • Check passwords are correct in keystore.properties

"Install Failed" on Phone

  • Enable "Install from unknown sources" or "Allow from this source"
  • Check Android version compatibility (app requires Android 8.0+)
  • Uninstall old version first if upgrading

ADB Not Detecting Phone

  • Enable Developer Options on phone (tap Build Number 7 times)
  • Enable USB Debugging in Developer Options
  • Accept "Allow USB debugging" prompt on phone
  • Try adb kill-server && adb start-server

Different Account/OAuth Issues

  • Both devices must authenticate with same Authentik account
  • Check auth.dnspegasus.net is accessible from both devices
  • Verify OAuth callback is working (alfredmobile://oauth/callback)

Alarm Doesn't Sync

  • Check proxy logs: tail -f /tmp/alfred-proxy-new.log
  • Verify both devices connected: look for "Client WebSocket state: 1"
  • Check broadcast count matches device count
  • Test WebSocket with: adb logcat | grep GatewayClient

Distribution Options

  • Debug APK - No signing needed, install directly on your devices
  • Works for testing and personal use
  • Cannot publish to Play Store
  • Shows "Debug" in app version

For Beta Testing

  • Release APK (signed) - Proper signing, can distribute to testers
  • Upload to Google Play Console (Internal Testing track)
  • Or distribute directly via email/download link
  • Users need to enable "Install from unknown sources"

For Public Distribution

  • Play Store - Requires Google Play Console account ($25 one-time fee)
  • Upload signed release APK
  • Fill in app listing details
  • Submit for review
  • Can use internal/alpha/beta/production tracks

Build Variants

Debug vs Release

Debug:

  • Faster builds (no minification)
  • Includes debug symbols
  • Larger APK size (~25MB)
  • Shows debug logs
  • No signing required

Release:

  • Slower builds (ProGuard minification)
  • Optimized code
  • Smaller APK size (~15MB)
  • No debug logs
  • Requires signing

Build Flavors (if added)

Could add build flavors for:

  • dev - Development (points to localhost)
  • staging - Staging environment
  • production - Production (alfred-app.dnspegasus.net)

Currently using single flavor with environment-based config.

Version Management

Update version in app/build.gradle.kts:

android {
    defaultConfig {
        versionCode = 2  // Increment for each release
        versionName = "1.0.1"  // User-visible version
    }
}

Version naming:

  • Major.Minor.Patch (e.g., 1.0.1)
  • versionCode must increment for Play Store updates
  • versionName is display-only

Useful Commands

# Clean build
./gradlew clean

# Build all variants
./gradlew build

# Run tests
./gradlew test

# Check for outdated dependencies
./gradlew dependencyUpdates

# List all tasks
./gradlew tasks

# Analyze APK size
~/android-dev/android-sdk/build-tools/*/apkanalyzer apk summary app-debug.apk

Security Notes

  • Never commit keystore or keystore.properties to git
  • Add to .gitignore: *.keystore, keystore.properties
  • Back up keystore securely (losing it means no updates to app)
  • Use strong passwords for keystore
  • Keep keystore password in password manager

Next Steps After Building

  1. Install on multiple devices
  2. Test cross-device alarm dismissal
  3. Test in different network conditions (WiFi, mobile data)
  4. Verify OAuth flow works on all devices
  5. Check battery usage over extended period
  6. Test alarm reliability overnight

Support

See also: