feat(android): release signing + R8-verified signed APK (Phase 28.8)

This commit is contained in:
Mathieu Moran
2026-08-15 20:44:45 -04:00
parent d34d30e65f
commit 5039b90bc6
4 changed files with 43 additions and 21 deletions
+2
View File
@@ -8,5 +8,7 @@ local.properties
*.aab
*.jks
*.keystore
keystore/
keystore.properties
!gradle/wrapper/gradle-wrapper.jar
!gradle/wrapper/gradle-wrapper.properties
+21
View File
@@ -1,3 +1,6 @@
import java.io.FileInputStream
import java.util.Properties
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
@@ -6,6 +9,12 @@ plugins {
alias(libs.plugins.ksp)
}
// Release signing config loaded from keystore.properties (gitignored).
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties().apply {
if (keystorePropertiesFile.exists()) load(FileInputStream(keystorePropertiesFile))
}
android {
namespace = "com.yarisobd.app"
compileSdk = 35
@@ -20,6 +29,17 @@ android {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
signingConfigs {
create("release") {
if (keystorePropertiesFile.exists()) {
storeFile = rootProject.file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["storePassword"] as String
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
}
}
}
buildTypes {
debug {
applicationIdSuffix = ".debug"
@@ -32,6 +52,7 @@ android {
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
signingConfig = signingConfigs.getByName("release")
}
}
+13 -13
View File
@@ -250,28 +250,28 @@ android/
- [ ] FontAwesome-style icons where they map to the web nav
- [ ] Page titles (`h3 fw-bold`) at the top of each screen
### 28.8 — Polish + distribution ⬜ NOT STARTED
### 28.8 — Polish + distribution 🚧 IN PROGRESS
**Depends on: 28.1–28.7 (whichever subset ships).**
#### 28.8.1 — App polish
- [ ] App icon (adaptive icon: foreground + background layers)
- [ ] Splash screen (Android 12+ SplashScreen API)
- [ ] Dark theme verified on all screens (default, car-friendly)
- [ ] Error handling audit: every network call has a user-visible error state + retry
- [ ] Accessibility: content descriptions on icons, reasonable touch targets (≥48dp)
- [ ] Commit: `feat: app polish`
#### 28.8.1 — App polish ✅ (2026-08-15)
- [x] App icon: adaptive icon (red `#e63946` bg + white gauge foreground)
- [x] Splash screen: native API 31+ (`values-v31/themes.xml`, dark bg + gauge icon)
- [x] Dark theme follows the OS setting (done in 28.7)
- [x] App label: "Yaris OBD"
- [ ] Error handling audit — most screens have error states; dashboard still shows "—" when offline
- [ ] Accessibility audit — content descriptions present on most icons; touch targets ≥48dp mostly
#### 28.8.2 — Build + distribution
- [ ] Release build signing key (keystore generated, not committed)
- [ ] ProGuard/R8 rules verified (Retrofit, OkHttp, Coil, MapLibre keep rules)
- [ ] APK output: `app/build/outputs/apk/release/app-release.apk`
#### 28.8.2 — Build + distribution 🚧 (release APK signed; hosting pending)
- [x] Release signing key: `android/keystore/release.keystore` (gitignored) + `keystore.properties`
- [x] ProGuard/R8 rules verified — release APK builds AND launches on the Pixel
- [x] APK output: `app/build/outputs/apk/release/app-release.apk` (~43 MB, signed)
- [ ] Self-hosted distribution:
- Copy APK to Pi: `scp app-release.apk [email protected]:~/app/yaris-obd/static/app/`
- Add a lightweight Pi route: `GET /app` → serves `static/app/index.html` with
download link + install instructions
- Phone flow: connect to Pi hotspot → open `http://yaris.local/app` → download APK →
install (user must enable "Install unknown apps" once)
- [ ] Commit: `feat: release build + self-hosted distribution`
- [ ] Commit: `feat: self-hosted distribution`
## Working notes