# ๐ง RR3 OTA Integration Guide
**Step-by-step guide to integrate the OTA update system into any RR3 APK**
---
## ๐ Prerequisites
### Tools Needed
- **apktool** - For decompiling/recompiling APKs
- **Java JDK 8+** - For compiling Java to class files
- **dx tool** (Android SDK) - For converting class to dex
- **baksmali/smali** - For dex to smali conversion
- **zipalign** - For optimizing APK
- **apksigner** - For signing APK
- **Text editor** - For editing files
### Install Tools
```bash
# apktool
wget https://github.com/iBotPeaches/Apktool/releases/latest/download/apktool.jar
# Android SDK (includes dx, zipalign, apksigner)
# Download from: https://developer.android.com/studio
# baksmali/smali
wget https://github.com/JesusFreke/smali/releases/latest/download/baksmali.jar
wget https://github.com/JesusFreke/smali/releases/latest/download/smali.jar
```
---
## ๐ฏ Integration Steps
### Step 1: Decompile Your APK
```bash
# Decompile RR3 APK
apktool d your-rr3.apk -o rr3-decompiled
cd rr3-decompiled
```
**Output structure:**
```
rr3-decompiled/
โโโ AndroidManifest.xml
โโโ smali/
โโโ assets/
โโโ res/
โโโ ...
```
---
### Step 2: Add UpdateManager
#### Option A: Use Precompiled Smali (Easier)
```bash
# Create directory
mkdir -p smali/com/community
# Copy UpdateManager.smali
cp /path/to/rr3-ota/UpdateManager.smali smali/com/community/
```
#### Option B: Compile from Java (More Control)
```bash
# Compile Java to class
javac -source 1.8 -target 1.8 \
-cp android.jar:org.json.jar \
UpdateManager.java
# Convert class to dex
dx --dex --output=UpdateManager.dex UpdateManager.class
# Convert dex to smali
baksmali d UpdateManager.dex -o smali-output
# Copy to APK
mkdir -p smali/com/community
cp smali-output/com/community/UpdateManager.smali smali/com/community/
```
#### Important: Update Version Constants
Edit `smali/com/community/UpdateManager.smali`:
**Find these lines:**
```smali
.field private static final CURRENT_VERSION:Ljava/lang/String; = "15.0.0-community-alpha"
.field private static final CURRENT_VERSION_CODE:I = 0x249f0
```
**Change to your version:**
```smali
.field private static final CURRENT_VERSION:Ljava/lang/String; = "14.5.0" # Your version
.field private static final CURRENT_VERSION_CODE:I = 0x224D4 # 140500 in hex
```
**Calculate version code:**
```
versionCode = (major * 10000) + (minor * 100) + patch
Examples:
14.5.0 โ 140500 โ 0x224D4 (hex)
15.0.0 โ 150000 โ 0x249F0 (hex)
# Convert to hex: printf '%x\n' 140500
```
#### Update Manifest URL
**Find this line:**
```smali
.field private static final UPDATE_API_URL:Ljava/lang/String; = "https://raw.githubusercontent.com/project-real-resurrection-3/rr3-releases/main/versions.json"
```
**Change to your manifest URL:**
```smali
.field private static final UPDATE_API_URL:Ljava/lang/String; = "https://raw.githubusercontent.com/YOUR-ORG/YOUR-REPO/main/versions.json"
```
---
### Step 3: Add HTML UI
```bash
# Copy update checker HTML
cp /path/to/rr3-ota/community_update_checker.html assets/
```
**Verify placement:**
```
assets/
โโโ community_update_checker.html
```
---
### Step 4: Add Permissions
Edit `AndroidManifest.xml`:
```xml
```
---
### Step 5: Integrate into Your UI
You need to add a button/menu item that triggers the update checker.
#### Example: Add to Main Menu WebView
**Find your main menu HTML file** (usually in `assets/`):
```bash
# Search for HTML files
find assets/ -name "*.html" | grep -i menu
```
**Add update button:**
```html
```
#### Add WebView Bridge
**Find the Activity that creates your WebView** (in `smali/`):
Common locations:
- `smali/com/ea/games/*/MainActivity.smali`
- `smali/com/ea/games/*/WebViewActivity.smali`
**Find where WebView is created:**
```smali
# Look for this pattern
new-instance v0, Landroid/webkit/WebView;
invoke-direct {v0, p0}, Landroid/webkit/WebView;->(Landroid/content/Context;)V
```
**Add JavaScript interface after WebView creation:**
```smali
# Create UpdateManager instance
new-instance v1, Lcom/community/UpdateManager;
move-object v2, p0 # context
invoke-direct {v1, v2}, Lcom/community/UpdateManager;->(Landroid/content/Context;)V
# Add as JavaScript interface
const-string v2, "UpdateManager"
invoke-virtual {v0, v1, v2}, Landroid/webkit/WebView;->addJavascriptInterface(Ljava/lang/Object;Ljava/lang/String;)V
```
---
### Step 6: Recompile APK
```bash
# Build APK
apktool b rr3-decompiled -o rr3-modified-unsigned.apk
# Zipalign
zipalign -p -f -v 4 rr3-modified-unsigned.apk rr3-modified-aligned.apk
# Sign APK (create keystore if needed)
# Create keystore (first time only):
keytool -genkey -v -keystore rr3.keystore -alias rr3-key -keyalg RSA -keysize 2048 -validity 10000
# Sign
apksigner sign --ks rr3.keystore --ks-key-alias rr3-key \
--out rr3-modified-signed.apk \
rr3-modified-aligned.apk
# Verify signature
apksigner verify rr3-modified-signed.apk
```
**Final APK:** `rr3-modified-signed.apk`
---
### Step 7: Test Installation
```bash
# Install on device
adb install rr3-modified-signed.apk
# Or manually:
# 1. Transfer APK to device
# 2. Enable "Install from Unknown Sources"
# 3. Tap APK to install
```
---
## ๐งช Testing the Integration
### Test 1: WebView Bridge
Open your app and run in Android Studio logcat:
```bash
adb logcat | grep UpdateManager
```
**Expected:** Should see `UpdateManager` logs when app starts.
### Test 2: UI Button
1. Open your modified menu
2. Click "Check for Updates" button
3. Should navigate to update checker page
**If it doesn't work:**
- Check `assets/community_update_checker.html` exists
- Verify path: `file:///android_asset/community_update_checker.html`
### Test 3: Update Check
1. Click "Check for Updates" in the UI
2. Watch logcat: `adb logcat | grep UpdateManager`
**Expected logs:**
```
I/UpdateManager: Checking for updates from manifest...
I/UpdateManager: No update available
```
Or if update exists:
```
I/UpdateManager: Update available: 15.1.0
```
### Test 4: Download
1. Create a test release on GitHub
2. Update your `versions.json` manifest
3. Check for updates in app
4. Click "Download Update"
5. Verify download starts
---
## ๐ Troubleshooting
### Issue: "Class not found: UpdateManager"
**Cause:** UpdateManager.smali not in correct location
**Fix:**
```bash
# Verify file exists
ls -la smali/com/community/UpdateManager.smali
# Should be:
# smali/com/community/UpdateManager.smali
# NOT: smali/UpdateManager.smali
```
### Issue: "JavaScript interface not found"
**Cause:** WebView bridge not added or incorrect
**Fix:**
- Verify you added the JavaScript interface code
- Check the interface name matches: `"UpdateManager"`
- Make sure it's added BEFORE WebView loads content
### Issue: "Update check returns error"
**Cause:** Manifest URL incorrect or not accessible
**Fix:**
```bash
# Test manifest URL manually
curl https://raw.githubusercontent.com/YOUR-ORG/YOUR-REPO/main/versions.json
# Should return JSON, not 404
```
### Issue: "Version code mismatch"
**Cause:** Incorrect version code calculation
**Fix:**
```bash
# Calculate version code
echo "scale=0; (14*10000) + (5*100) + 0" | bc
# Result: 140500
# Convert to hex
printf '%x\n' 140500
# Result: 224d4
# Update in smali:
.field private static final CURRENT_VERSION_CODE:I = 0x23ab8
```
### Issue: "APK won't install"
**Cause:** Signature mismatch or corrupted APK
**Fix:**
```bash
# Verify APK
apksigner verify rr3-modified-signed.apk
# If invalid, rebuild and re-sign
apktool b rr3-decompiled -o new.apk
zipalign -p 4 new.apk aligned.apk
apksigner sign --ks rr3.keystore aligned.apk
```
---
## ๐ฑ Platform-Specific Notes
### Android 11+ (API 30+)
**File access changes:** Need to use scoped storage
**In UpdateManager.smali, update download destination:**
```java
// Old (doesn't work on Android 11+):
Environment.DIRECTORY_DOWNLOADS
// New (works on all versions):
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
```
### Android 8+ (API 26+)
**Install unknown apps permission required**
Add to `AndroidManifest.xml`:
```xml
```
---
## ๐ Security Checklist
Before releasing:
- [ ] Version constants updated
- [ ] Manifest URL points to your repository
- [ ] APK signed with your keystore (not debug key!)
- [ ] Permissions added to AndroidManifest.xml
- [ ] SHA-256 checksums in manifest (optional but recommended)
- [ ] HTTPS used for all URLs
- [ ] Tested on multiple Android versions
---
## ๐ Version Manifest Setup
After integration, you need a manifest:
### 1. Create GitHub Repository
```bash
# Create releases repository
gh repo create YOUR-ORG/rr3-releases --public
```
### 2. Create versions.json
```json
{
"schema_version": 1,
"last_updated": "2026-02-24T00:00:00Z",
"channels": {
"stable": {
"description": "Stable releases",
"latest": "14.5.0"
}
},
"versions": [
{
"version": "14.5.0",
"version_code": 140500,
"channel": "stable",
"release_date": "2026-02-24",
"min_android": 21,
"target_android": 33,
"download_url": "https://github.com/YOUR-ORG/rr3-releases/releases/download/v14.5.0/RR3-v14.5.0.apk",
"file_size": 230000000,
"sha256": "your-sha256-here",
"changelog": "## What's New\n- Your changelog here",
"upgrade_from": []
}
]
}
```
### 3. Upload to GitHub
```bash
git add versions.json
git commit -m "Add version manifest"
git push
```
### 4. Verify Accessibility
```bash
curl https://raw.githubusercontent.com/YOUR-ORG/rr3-releases/main/versions.json
```
---
## ๐ You're Done!
Your RR3 APK now has a fully functional OTA update system!
**Next steps:**
1. Release your first version on GitHub
2. Update versions.json when new versions are ready
3. Users will automatically see updates
---
## ๐ Need Help?
- ๐ **Full documentation:** [README.md](./README.md)
- ๐ **Report issues:** GitHub Issues
- ๐ฌ **Community:** Discord (link TBA)
- ๐ง **Contact:** [@ssfdre38](https://github.com/ssfdre38)
---
**Happy integrating! ๐๐**