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).
116 lines
4.4 KiB
Kotlin
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
|
|
}
|
|
}
|
|
}
|