plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'org.jetbrains.kotlin.plugin.serialization' } android { compileSdk 32 defaultConfig { applicationId "chat.simplex.app" minSdk 26 targetSdk 32 versionCode 111 versionName "4.6.1-beta.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary true } externalNativeBuild { cmake { cppFlags '' } } manifestPlaceholders.app_name = "@string/app_name" manifestPlaceholders.provider_authorities = "chat.simplex.app.provider" manifestPlaceholders.extract_native_libs = compression_level != "0" } buildTypes { debug { applicationIdSuffix "$application_id_suffix" debuggable new Boolean("$enable_debuggable") manifestPlaceholders.app_name = "$app_name" // Provider can't be the same for different apps on the same device manifestPlaceholders.provider_authorities = "chat.simplex.app${application_id_suffix}.provider" } release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' freeCompilerArgs += "-opt-in=kotlinx.coroutines.DelicateCoroutinesApi" freeCompilerArgs += "-opt-in=androidx.compose.foundation.ExperimentalFoundationApi" freeCompilerArgs += "-opt-in=androidx.compose.ui.text.ExperimentalTextApi" freeCompilerArgs += "-opt-in=androidx.compose.material.ExperimentalMaterialApi" freeCompilerArgs += "-opt-in=com.google.accompanist.insets.ExperimentalAnimatedInsets" freeCompilerArgs += "-opt-in=com.google.accompanist.permissions.ExperimentalPermissionsApi" freeCompilerArgs += "-opt-in=kotlinx.serialization.InternalSerializationApi" freeCompilerArgs += "-opt-in=kotlinx.serialization.ExperimentalSerializationApi" } externalNativeBuild { cmake { path file('src/main/cpp/CMakeLists.txt') } } buildFeatures { compose true } composeOptions { kotlinCompilerExtensionVersion compose_version } packagingOptions { resources { excludes += '/META-INF/{AL2.0,LGPL2.1}' } jniLibs.useLegacyPackaging = compression_level != "0" } def isRelease = gradle.getStartParameter().taskNames.find({ it.toLowerCase().contains("release") }) != null def isBundle = gradle.getStartParameter().taskNames.find({ it.toLowerCase().contains("bundle") }) != null // if (isRelease) { // Comma separated list of languages that will be included in the apk android.defaultConfig.resConfigs("en", "cs", "de", "es", "fr", "it", "nl", "ru", "zh-rCN") // } if (isBundle) { defaultConfig.ndk.abiFilters 'arm64-v8a', 'armeabi-v7a' } else { splits { abi { enable true reset() if (isRelease) { include 'arm64-v8a', 'armeabi-v7a' } else { include 'arm64-v8a', 'armeabi-v7a' universalApk false } } } } } dependencies { implementation 'androidx.core:core-ktx:1.7.0' implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.compose.material:material:$compose_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1' implementation 'androidx.lifecycle:lifecycle-process:2.4.1' implementation 'androidx.activity:activity-compose:1.4.0' implementation 'androidx.fragment:fragment:1.4.1' implementation 'org.jetbrains.kotlinx:kotlinx-datetime:0.3.2' implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2' implementation "androidx.compose.material:material-icons-extended:$compose_version" implementation "androidx.compose.ui:ui-util:$compose_version" implementation "androidx.navigation:navigation-compose:2.4.1" implementation "com.google.accompanist:accompanist-insets:0.23.0" implementation 'androidx.webkit:webkit:1.4.0' implementation "com.godaddy.android.colorpicker:compose-color-picker:0.4.2" def work_version = "2.7.1" implementation "androidx.work:work-runtime-ktx:$work_version" implementation "androidx.work:work-multiprocess:$work_version" def camerax_version = "1.1.0-beta01" implementation "androidx.camera:camera-core:${camerax_version}" implementation "androidx.camera:camera-camera2:${camerax_version}" implementation "androidx.camera:camera-lifecycle:${camerax_version}" implementation "androidx.camera:camera-view:${camerax_version}" //Barcode implementation 'org.boofcv:boofcv-android:0.40.1' implementation 'org.boofcv:boofcv-core:0.40.1' //Camera Permission implementation "com.google.accompanist:accompanist-permissions:0.23.0" implementation "com.google.accompanist:accompanist-pager:0.25.1" // Link Previews implementation 'org.jsoup:jsoup:1.13.1' // Biometric authentication implementation 'androidx.biometric:biometric:1.2.0-alpha04' // GIFs support implementation "io.coil-kt:coil-compose:2.1.0" implementation "io.coil-kt:coil-gif:2.1.0" // Video support implementation "com.google.android.exoplayer:exoplayer:2.17.1" testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" } // Don't do anything if no compression is needed if (compression_level != "0") { tasks.whenTaskAdded { task -> if (task.name == 'packageDebug') { task.finalizedBy compressApk } else if (task.name == 'packageRelease') { task.finalizedBy compressApk } } } tasks.register("compressApk") { doLast { def isRelease = gradle.getStartParameter().taskNames.find({ it.toLowerCase().contains("release") }) != null def buildType if (isRelease) { buildType = "release" } else { buildType = "debug" } def javaHome = System.properties['java.home'] ?: org.gradle.internal.jvm.Jvm.current().getJavaHome() def sdkDir = android.getSdkDirectory().getAbsolutePath() def keyAlias = "" def keyPassword = "" def storeFile = "" def storePassword = "" if (project.properties['android.injected.signing.key.alias'] != null) { keyAlias = project.properties['android.injected.signing.key.alias'] keyPassword = project.properties['android.injected.signing.key.password'] storeFile = project.properties['android.injected.signing.store.file'] storePassword = project.properties['android.injected.signing.store.password'] } else if (android.signingConfigs.hasProperty(buildType)) { def gradleConfig = android.signingConfigs[buildType] keyAlias = gradleConfig.keyAlias keyPassword = gradleConfig.keyPassword storeFile = gradleConfig.storeFile storePassword = gradleConfig.storePassword } else { // There is no signing config for current build type, can't sign the apk println("No signing configs for this build type: $buildType") return } def outputDir = tasks["package${buildType.capitalize()}"].outputs.files.last() exec { workingDir '../../../scripts/android' setEnvironment(['JAVA_HOME': "$javaHome"]) commandLine './compress-and-sign-apk.sh', \ "$compression_level", \ "$outputDir", \ "$sdkDir", \ "$storeFile", \ "$storePassword", \ "$keyAlias", \ "$keyPassword" } if (project.properties['android.injected.signing.key.alias'] != null && buildType == 'release') { new File(outputDir, "app-release.apk").renameTo(new File(outputDir, "simplex.apk")) new File(outputDir, "app-armeabi-v7a-release.apk").renameTo(new File(outputDir, "simplex-armv7a.apk")) new File(outputDir, "app-arm64-v8a-release.apk").renameTo(new File(outputDir, "simplex.apk")) } // View all gradle properties set // project.properties.each { k, v -> println "$k -> $v" } } }