I have an Android Gradle project with several flavors (different styles of the same app). I have a task that downloads some external file and puts it into assets folder. I need to specify an array of strings as a part of each flavor that (urls or filenames) that will be downloaded during the build of a specific flavor.
```
applicationVariants.all { variant ->
if (variant.buildType.name == 'release') {
variant.outputs.all {
def currentProductFlavor = variant.productFlavors.name.get(0)
def apkName = rootProject.ext.app.appName + currentProductFlavor + "_" + rootProject.ext.app.appVersionName + ".apk"
println("======apkName:" + apkName)
outputFileName = apkName
}
}
}
```
Related
applicationVariants.all { variant ->
variant.outputs.each { output ->
//noinspection GroovyAssignabilityCheck
output.outputFile = new File(output.outputFile.parent,
output.outputFile.name.replace(".apk", "-${variant.versionName}.apk"))
}
}
Need a clarification about the above code.
Did the only purpose to rename generated .apk file?
Why do I need to add this line //noinspection GroovyAssignabilityCheck ?
Would the above line be cause for run-time crash or any issue ?
What else can I do with applicationVariants.all {} ?
1 Yes, only rename
2 Not sure. outputFile is read-only - this code shouldn't work on newest Gradle
3 No, Gradle doesn't affect to runtime
4 Every Gradle action
Your above code is not working in Android studio 3.2.1.
If want to rename the APK and want to extract proguard mapping file.
applicationVariants.all { variant ->
if (variant.buildType.name == "release") {
def formattedDate = new Date().format('ddMMMyy_HH_mm')
variant.outputs.all { output ->
def formattedName = "${"SampleName" + variant.productFlavors.get(0).name.concat("_")}" +
"${variant.buildType.name[0].toUpperCase().concat("_v")}${variant.versionName.concat("_" + formattedDate)}"
outputFileName = new File("${"v"+variant.versionName.concat("/")}" +formattedName+".apk")
if (variant.getBuildType().isMinifyEnabled()) {
copy {
from variant.mappingFile
into output.outputFile.parent
rename { String fileName ->
formattedName + "_mapping.txt"
}
}
}
}
}
}
Above code will give the apk with /BuildVariant/vVersionName/ SampleName_BuildVariant_BuildType_vVersionName_DDMMMYY_HH_mm.apk and mapping file.
You can also set do all above thing only on release build
I'm building APKs from command line as follows
./gradlew assembleProductionRelease
Are there any configuration params which will allow to add buildNumber and versionNumber to APK file name automatically? By default APK file will be named as app-production-release.
You can try/adapt this code (add it to your build.gradle):
applicationVariants.all { variant ->
variant.outputs.all { output ->
def sep = '_'
def version = variant.versionName
def build = variant.versionCode
outputFileName = "${rootProject.name}${sep}" +
"${variant.buildType.name}${sep}" +
"${version}${sep}" +
"build${sep}${build}.apk"
}
}
I'm composing .apk filename using current app version and flavor name. I'd like to add current ABI split name as well, but only if it's a universal apk.
My relevant build.gradle sections:
buildTypes {
release {
applicationVariants.all { variant ->
variant.outputs.each { output ->
def flavor = .... // some code to parse flavor & determine an appropriate string from it
output.outputFile = new File(output.outputFile.parent, "app_" + flavor + "_0" + variant.versionCode + ".apk")
}
}
}
}
productFlavors {
deploy {
splits {
abi {
enable true
reset()
include 'armeabi-v7a' //select ABIs to build APKs for
universalApk true //generate an additional APK that contains all the ABIs
}
}
}
}
Currently this config generates two .apks, but they both have the same file name as I don't know how to get the ABI name, so the one generated later overwrites the one generated before.
So, what is the equivalent variant.productFlavors.get(0) for current ABI split?
That's very strange as flavor and ABI-name is automatically added to build name (if you make corresponding assemble)
can you try completely remove your custom made naming
applicationVariants.all { variant ->
variant.outputs.each { output ->
def flavor = .... // some code to parse flavor & determine an appropriate string from it
output.outputFile = new File(output.outputFile.parent, "app_" + flavor + "_0" + variant.versionCode + ".apk")
}
}
and instead of that try to add to defaultConfig this line
archivesBaseName = "app_${versionCode}"
If this is will not resolve you issues you can try to get abi from output
output.getFilter(com.android.build.OutputFile.ABI)
The equivalent is output.getFilter(com.android.build.OutputFile.ABI).
Note that, starting with Android Studio 3.0, you should use outputFileName and variant.outputs.all instead:
applicationVariants.all { variant ->
variant.outputs.all { output ->
outputFileName = "app_" + output.getFilter(com.android.build.OutputFile.ABI) + "_0" + variant.versionCode + ".apk"
}
}
I'm trying to deal with google-services.json and different flavors. The documentation says that we need the file in the root folder.
I got a task that can easily copy the file from the flavor folder to the root folder:
task CopyToRoot(type: Copy) {
def appModuleRootFolder = '.'
def srcDir = 'src'
def googleServicesJson = 'google-services.json'
outputs.upToDateWhen { false }
def flavorName = android.productFlavors.flavor1.name
description = "Switches to $flavorName $googleServicesJson"
delete "$appModuleRootFolder/$googleServicesJson"
from "${srcDir}/$flavorName/"
include "$googleServicesJson"
into "$appModuleRootFolder"
}
Then, in the afterEvaluate I force
afterEvaluate {
processFlavor1DebugGoogleServices.dependsOn CopyToRoot
processFlavor1ReleaseGoogleServices.dependsOn CopyToRoot
}
This works only for 1 flavor (defined statically). How to do this for every flavor? I got 4 flavors. How to get the current flavor that is being compiled?
[UPDATE 1] -
Also tried:
task CopyToRoot(type: Copy) {
def appModuleRootFolder = '.'
def srcDir = 'src'
def googleServicesJson = 'google-services.json'
outputs.upToDateWhen { false }
def flavorName = android.productFlavors.flavor1.name
android.applicationVariants.all { variant ->
def flavorString = variant.getVariantData().getVariantConfiguration().getFlavorName()
println('flavorString: ' + flavorString)
description = "Switches to $flavorString $googleServicesJson"
delete "$appModuleRootFolder/$googleServicesJson"
from "${srcDir}/$flavorString/"
include "$googleServicesJson"
into "$appModuleRootFolder"
}
}
But this doesn't copy the correct file. Any help?
A way to go is to create a folder named "google-services" in each flavor, containing both the debug version and the release version of the json file :
In the buildTypes section of your gradle file, add this :
applicationVariants.all { variant ->
def buildTypeName = variant.buildType.name
def flavorName = variant.productFlavors[0].name;
def googleServicesJson = 'google-services.json'
def originalPath = "src/$flavorName/google-services/$buildTypeName/$googleServicesJson"
def destPath = "."
copy {
if (flavorName.equals(getCurrentFlavor()) && buildTypeName.equals(getCurrentBuildType())) {
println originalPath
from originalPath
println destPath
into destPath
}
}
}
It will copy the right json file at the root of your app module automatically when you'll switch build variant.
Add the two methods called to get the current flavor and current build type at the root of your build.gradle
def getCurrentFlavor() {
Gradle gradle = getGradle()
String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
Pattern pattern;
if( tskReqStr.contains( "assemble" ) )
pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
else
pattern = Pattern.compile("generate(\\w+)(Release|Debug)")
Matcher matcher = pattern.matcher( tskReqStr )
if( matcher.find() ) {
println matcher.group(1).toLowerCase()
return matcher.group(1).toLowerCase()
}
else
{
println "NO MATCH FOUND"
return "";
}
}
def getCurrentBuildType() {
Gradle gradle = getGradle()
String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
if (tskReqStr.contains("Release")) {
println "getCurrentBuildType release"
return "release"
}
else if (tskReqStr.contains("generateDebug")) {
println "getCurrentBuildType debug"
return "debug"
}
println "NO MATCH FOUND"
return "";
}
Based on this answer
I found my answer. Google finally supports different google-services.json per flavor. You just need to update the plugin to com.google.gms:google-services:2.0.0.
There's no need to copy the json file to the app folder, just put your google-services.json different files inside your build flavors directories.
I am trying to configure my build.gradle file to only execute a gradle task when the release build variant is selected. So far, my task always gets executed, whether it is in my debug or release build types or signing configs. I have tried adding my task inside an applicationsVariants block and check if it is the release variant, but it just loops through all variants.
applicationVariants.all { variant ->
variant.outputs.each { output ->
...
}
}
I know that both the debug and release tasks always run for whichever build variant you choose. Is it possible to execute some code only when creating a build for release? If so, where does that code go? Thanks!
I have read through every Stackoverflow question on this, but none of the answers really did I am wanting. My end goal is when I select the "release" build variant for a Play Store build, a message is posted to our server. I do not want this to happen when just debugging.
Add doFirst or doLast for the build type you are interested in.
android.applicationVariants.all { variant ->
if ( variant.buildType.name == "release"){
variant.assemble.doLast { // Can also use doFirst here to run at the start.
logger.lifecycle("we have successfully built $v.name and can post a messaage to remote server")
}
}
}
I had to do something like this to check build version:
buildTypes {
applicationVariants.all { variant ->
variant.outputs.each {output ->
def project = "AppName"
def separator = "_"
/*def flavor = variant.productFlavors[0].name*/
def buildType = variant.variantData.variantConfiguration.buildType.name
def versionName = variant.versionName
def versionCode = variant.versionCode
def date = new Date();
def formattedDate = date.format('yyyyMMdd_HHmm')
if (variant.buildType.name == "release"){
def newApkName = project + separator + "v" + versionName + separator + versionCode + separator + buildType + separator + formattedDate + ".apk"
output.outputFile = new File(output.outputFile.parent, newApkName)
}
if (variant.buildType.name == "debug"){
def newApkName = project + separator + "v" + versionName + separator + versionCode + separator + buildType + ".apk"
output.outputFile = new File(output.outputFile.parent, newApkName)
}
}
} }