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
This commit is contained in:
305
BUILD_RELEASE.md
Normal file
305
BUILD_RELEASE.md
Normal file
@@ -0,0 +1,305 @@
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
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:**
|
||||
```bash
|
||||
# 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:**
|
||||
```bash
|
||||
# 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)
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```kotlin
|
||||
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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
# 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**:
|
||||
```bash
|
||||
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:
|
||||
```bash
|
||||
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
|
||||
|
||||
### 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 environment
|
||||
- `production` - Production (alfred-app.dnspegasus.net)
|
||||
|
||||
Currently using single flavor with environment-based config.
|
||||
|
||||
## Version Management
|
||||
|
||||
Update version in `app/build.gradle.kts`:
|
||||
|
||||
```kotlin
|
||||
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
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
- `CROSS_DEVICE_ALARMS.md` - Cross-device testing guide
|
||||
- `ARCHITECTURE.md` - System architecture overview
|
||||
- `README.md` - General app documentation
|
||||
- Official Android docs: https://developer.android.com/studio/publish
|
||||
Reference in New Issue
Block a user