# 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
