- 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
8.0 KiB
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
- Build APK (debug or release)
- Install on tablet:
adb -s adb-R52R30ASB4Y-BIkpas install -r app-debug.apk - Install on phone:
- Transfer APK to phone
- Enable "Install from unknown sources" in phone settings
- Open APK file and install
- OR use
adb installif phone has ADB enabled
Testing Procedure
See CROSS_DEVICE_ALARMS.md for full testing procedure.
Quick test:
- Open Alfred app on both devices
- Authenticate on both (same account)
- 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}' - Verify alarm triggers on both devices
- Dismiss on ONE device
- 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
For Personal Use (Recommended)
- 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 environmentproduction- 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
- Install on multiple devices
- Test cross-device alarm dismissal
- Test in different network conditions (WiFi, mobile data)
- Verify OAuth flow works on all devices
- Check battery usage over extended period
- Test alarm reliability overnight
Support
See also:
CROSS_DEVICE_ALARMS.md- Cross-device testing guideARCHITECTURE.md- System architecture overviewREADME.md- General app documentation- Official Android docs: https://developer.android.com/studio/publish