Initial commit: RR3 OTA Update System
Complete standalone package for adding OTA (Over-The-Air) auto-updates to Real Racing 3 APK mods. Features: - Manifest-based version control (versions.json) - Prevents unwanted major version jumps - Material Design WebView UI - WiFi/mobile data download options - Preserves user data during updates - Multi-version channel support Package Contents: - UpdateManager.java - Source code implementation - UpdateManager.smali - Compiled smali for APK integration - community_update_checker.html - Material Design UI - README.md - Complete documentation - INTEGRATION-GUIDE.md - Step-by-step integration instructions Ready for integration into any RR3 APK version (v15, v14, v13, etc.) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
505
INTEGRATION-GUIDE.md
Normal file
505
INTEGRATION-GUIDE.md
Normal file
@@ -0,0 +1,505 @@
|
||||
# 🔧 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 = 0x23AB8 # 145000 in hex
|
||||
```
|
||||
|
||||
**Calculate version code:**
|
||||
```
|
||||
versionCode = (major * 100000) + (minor * 1000) + patch
|
||||
|
||||
Examples:
|
||||
14.5.0 → 145000 → 0x23AB8 (hex)
|
||||
15.0.0 → 150000 → 0x249F0 (hex)
|
||||
|
||||
# Convert to hex: printf '%x\n' 145000
|
||||
```
|
||||
|
||||
#### 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
|
||||
<manifest>
|
||||
<!-- Add these permissions -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
|
||||
<!-- Rest of manifest -->
|
||||
</manifest>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 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 to your menu -->
|
||||
<button onclick="checkForUpdates()" class="menu-button">
|
||||
🔄 Check for Updates
|
||||
</button>
|
||||
|
||||
<script>
|
||||
function checkForUpdates() {
|
||||
window.location.href = 'file:///android_asset/community_update_checker.html';
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
#### 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;-><init>(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;-><init>(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*100000) + (5*1000) + 0" | bc
|
||||
# Result: 145000
|
||||
|
||||
# Convert to hex
|
||||
printf '%x\n' 145000
|
||||
# Result: 23ab8
|
||||
|
||||
# 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
|
||||
<application>
|
||||
<activity android:name=".MainActivity">
|
||||
<!-- Add this -->
|
||||
<meta-data
|
||||
android:name="android.app.install_package"
|
||||
android:value="true" />
|
||||
</activity>
|
||||
</application>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 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": 145000,
|
||||
"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! 🔄🏁**
|
||||
Reference in New Issue
Block a user