tane/apps/app_seeds/android/app/build.gradle.kts
vjrj 071be44851
Some checks are pending
ci / analyze (push) Waiting to run
ci / test-commons-core (push) Waiting to run
ci / test-app-seeds (push) Waiting to run
site / deploy (push) Successful in 1m8s
perf(android): R8, bitmap downscaling, edge-to-edge; recover device compat; publish to production
Device compatibility (regression fix):
- The CAMERA permission (from zxing_barcode_scanner / image_picker) implicitly
  required android.hardware.camera, excluding camera-less devices — Play showed
  Automotive -96%, Chromebook -86%, TV -25%. Declare camera & location
  uses-feature required="false" to keep those devices supported.
- Detect a real camera at runtime (PackageManager.FEATURE_CAMERA_ANY via the
  existing MethodChannel), cache it at bootstrap, and hide the QR scan button and
  the camera photo-source option when absent, so no broken actions are offered.

Play "app optimization" recommendations:
- Enable R8 (isMinifyEnabled + isShrinkResources) with keep rules for the
  OCR (tesseract4android), SQLCipher and notifications JNI/reflection code.
- Bitmap downscaling: cacheWidth/cacheHeight (and ResizeImage for avatars) on
  list thumbnails and avatars so photos decode to on-screen size, not full res.
- Edge-to-edge: opt in with transparent system bars in main().

Release flow:
- Tagged builds now publish to the production track at 100% (was internal);
  add a manual deploy_internal lane as a QA safety net.
- Document country/region availability as a Play Console setting (not in-repo).
2026-07-20 22:53:48 +02:00

116 lines
4.4 KiB
Kotlin

import java.util.Properties
import java.io.FileInputStream
plugins {
id("com.android.application")
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
// Release signing is opt-in: drop a `key.properties` (gitignored) next to this
// module's android/ dir to sign release builds with your own keystore. Without
// it, release builds fall back to debug keys so contributors can still run
// `flutter run --release`. See docs/release.md.
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
val hasReleaseKeystore = keystorePropertiesFile.exists()
if (hasReleaseKeystore) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
android {
namespace = "org.comunes.tane"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
compileOptions {
// Required by flutter_local_notifications (uses Java 8+ APIs on older SDKs).
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}
defaultConfig {
applicationId = "org.comunes.tane"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
signingConfigs {
if (hasReleaseKeystore) {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = keystoreProperties["storeFile"]?.let { file(it) }
storePassword = keystoreProperties["storePassword"] as String
}
}
}
dependenciesInfo {
// No Google-encrypted dependency-metadata block in the APK/AAB
// signature: F-Droid rejects it, and Play does not require it.
includeInApk = false
includeInBundle = false
}
buildTypes {
release {
// Sign with the real release keystore when key.properties is present,
// otherwise fall back to debug keys so `flutter run --release` works
// for contributors without the signing material.
signingConfig = if (hasReleaseKeystore) {
signingConfigs.getByName("release")
} else {
signingConfigs.getByName("debug")
}
// R8: shrink + optimize + obfuscate the Java/Kotlin bytecode and strip
// unused resources — Play's "app optimization" recommendation (smaller
// download, less memory). Native .so libs are untouched, so this does
// not change device/ABI compatibility. Keep rules for reflection/JNI
// heavy deps (OCR, SQLCipher, notifications) live in proguard-rules.pro.
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}
}
}
flutter {
source = "../.."
}
dependencies {
// Backport of Java 8+ APIs, required by flutter_local_notifications.
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
}
// F-Droid builds one split APK per ABI (smaller downloads than a universal
// APK) and needs each split to carry a distinct versionCode so its repo can
// tell them apart; `flutter build apk --split-per-abi` alone gives every
// split the same versionCode. This override only touches the APK
// (applicationVariants) output, not the App Bundle Google Play consumes, so
// Play's per-device delivery is unaffected.
val abiVersionCodes = mapOf("armeabi-v7a" to 1, "arm64-v8a" to 2, "x86_64" to 3)
android.applicationVariants.all {
val variant = this
variant.outputs.all {
val output = this as com.android.build.gradle.internal.api.ApkVariantOutputImpl
val abi = output.getFilter(com.android.build.OutputFile.ABI)
abiVersionCodes[abi]?.let { abiCode ->
output.versionCodeOverride = variant.versionCode * 10 + abiCode
}
}
}