plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.compose) alias(libs.plugins.aboutLibrariesAndroid) alias(libs.plugins.protobuf) alias(libs.plugins.kotlin.serialization) } val abiCodes = mapOf( "arm64-v8a" to 0, "armeabi-v7a" to -1, "x86_64" to -2, ) android { namespace = "org.fairscan.app" compileSdk = 36 sourceSets["main"].assets.srcDir(layout.buildDirectory.dir("generated/assets")) defaultConfig { applicationId = "org.fairscan.app" // Based on tests against virtual devices, the app works with Android 8.0 (API level 26). // It crashes because of LiteRT on earlier versions. // LiteRT documentation only states that version 1.2.0 requires Android 12: // https://ai.google.dev/edge/litert/android/index minSdk = 26 targetSdk = 36 versionCode = 51 // increment by 3 because of ABI-specific APKs versionName = "1.13.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } val hasSigning = listOf( "RELEASE_STORE_FILE", "RELEASE_STORE_PASSWORD", "RELEASE_KEY_ALIAS", "RELEASE_KEY_PASSWORD" ).all { project.hasProperty(it) } signingConfigs { if (hasSigning) { create("release") { storeFile = file(project.property("RELEASE_STORE_FILE") as String) storePassword = project.property("RELEASE_STORE_PASSWORD") as String keyAlias = project.property("RELEASE_KEY_ALIAS") as String keyPassword = project.property("RELEASE_KEY_PASSWORD") as String } } } buildTypes { release { isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) if (hasSigning) { signingConfig = signingConfigs.getByName("release") } } } // See https://developer.android.com/build/configure-apk-splits val isBuildingBundle = gradle.startParameter.taskNames.any { it.lowercase().contains("bundle") } splits { abi { // Disable split ABIs when building appBundle: https://issuetracker.google.com/issues/402800800 isEnable = !isBuildingBundle reset() include(*abiCodes.keys.toTypedArray()) isUniversalApk = false } } applicationVariants.all { val variant = this variant.outputs .map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl } .forEach { output -> val abi = output.getFilter("ABI") output.outputFileName = "FairScan-${variant.versionName}-${abi}.apk" } } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } kotlin { compilerOptions { jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11) } } buildFeatures { compose = true buildConfig = true } } apply(from = "download-tflite.gradle.kts") dependencies { implementation(project(":imageprocessing")) { exclude(group = "org.openpnp", module = "opencv") } implementation(libs.androidx.core.ktx) implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.lifecycle.runtime.compose) implementation(libs.androidx.lifecycle.viewmodel.compose) implementation(libs.androidx.activity.compose) implementation(platform(libs.androidx.compose.bom)) implementation(libs.androidx.ui) implementation(libs.androidx.ui.graphics) implementation(libs.androidx.ui.tooling.preview) implementation(libs.androidx.material3) implementation(libs.androidx.camera.core) implementation(libs.androidx.camera.camera2) implementation(libs.androidx.camera.lifecycle) implementation(libs.androidx.camera.view) implementation(libs.androidx.datastore) implementation(libs.androidx.datastore.preferences) implementation(libs.androidx.documentfile) implementation(libs.protobuf.javalite) implementation(libs.litert) implementation(libs.litert.support) implementation(libs.litert.metadata) implementation(libs.opencv) implementation(libs.pdfbox) { // To reduce APK size exclude("org.bouncycastle") } implementation(libs.icons.extended) implementation(libs.zoomable) implementation(libs.reorderable) implementation(libs.aboutlibraries.compose.m3) implementation(libs.kotlinx.serialization.json) testImplementation(libs.junit) testImplementation(libs.assertj) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(platform(libs.androidx.compose.bom)) androidTestImplementation(libs.androidx.ui.test.junit4) debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) } aboutLibraries { library { // Enable the duplication mode, allows to merge, or link dependencies which relate duplicationMode = com.mikepenz.aboutlibraries.plugin.DuplicateMode.MERGE // Configure the duplication rule, to match "duplicates" with duplicationRule = com.mikepenz.aboutlibraries.plugin.DuplicateRule.SIMPLE } } protobuf { protoc { artifact = "com.google.protobuf:protoc:4.32.0" } generateProtoTasks { all().forEach { task -> task.builtins { create("java") { option("lite") } } } } } // See https://developer.android.com/build/configure-apk-splits androidComponents { onVariants { variant -> variant.outputs.forEach { output -> val name = output.filters.find { it.filterType == com.android.build.api.variant.FilterConfiguration.FilterType.ABI }?.identifier val baseAbiCode = abiCodes[name] if (baseAbiCode != null) { output.versionCode.set(output.versionCode.get() + baseAbiCode) } } } }