Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - change flavor version name based on build type

Tags:

android

gradle

I want to change version name for app flavors but only if it's a debug build.

(e.g. debug builds will have versions like 1.0.1 D (DEBUG) 555 or 1.0.1 P (DEBUG) 555, however I want the release builds only to have version like 1.0.1) How can I achieve this?

Basically I have these build types:

buildTypes {


    debug {
        versionNameSuffix " (DEBUG) " + mBuild

    }
    release {
        runProguard true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), file('proguard-project.txt')
        signingConfig signingConfigs.release
    }
}

and these flavors (for different api environment):

productFlavors {
    dev {
        versionName = android.defaultConfig.versionName + " D"
    }
    prod {
        versionName = android.defaultConfig.versionName + " P"
    }
}

Is there any way how to make release builds without product flavors version name change?

I've tried to set the version name dynamically via

    buildTypes.each { buildType ->
    if(buildType.name == 'debug') {
        productFlavors.dev.versionName = android.defaultConfig.versionName + " D"
    }
}

but this results in

Could not find property 'dev' on GroupableProductFlavorDsl container.

like image 248
martinpelant Avatar asked Nov 01 '13 11:11

martinpelant


People also ask

What is BuildConfig flavor?

BuildConfig.FLAVOR gives you combined product flavor. So if you have only one flavor dimension: productFlavors { normal { } admin { } } Then you can just check it: if (BuildConfig. FLAVOR.

What is flavorDimensions?

A flavorDimension is something like a flavor category and every combination of a flavor from each dimension will produce a variant. In your case, you must define one flavorDimension named "type" and another dimension named "organization".

What is Buildtype in Gradle Android?

A build type determines how an app is packaged. By default, the Android plug-in for Gradle supports two different types of builds: debug and release . Both can be configured inside the buildTypes block inside of the module build file.


3 Answers

After hours of searching I've managed to remove all the changes made to the version name for the release build using this code

applicationVariants.all { variant ->
    if (variant.buildType.name == 'release') {
        variant.mergedFlavor.versionName = android.defaultConfig.versionName;
    }
}
like image 138
martinpelant Avatar answered Sep 26 '22 08:09

martinpelant


For those wondering to use this using Kotlin DSL. At first try, it might not be allowing us to assign a new value to the version name.

enter image description here

The image above shown there's no setter for versionName for ProductFlavor class.

Attempt 1 (cast to ProductFlavorImpl):

applicationVariants.forEach { variant ->
  if (variant.buildType.name != "release") {
    variant.mergedFlavor.let {
      it as ProductFlavorImpl
      it.versionName = "sampingan-${defaultConfig.versionName}"
    }
  }
}

it as ProductFlavorImpl still doesn't work, due to MergedFlavor cannot be cast ProductFlavorImpl and throw this error:

com.android.builder.core.MergedFlavor cannot be cast to com.android.build.gradle.internal.api.dsl.model.ProductFlavorImpl

Attempt 2 (casting to MergedFlavor) instead:

  //
  variant.mergedFlavor.let {
    it as com.android.builder.core.MergedFlavor
  }
  // 

After trial & error, it looks like we were unable to directly change the versionName with MergedFlavor, instead another error logs shown below:

versionName cannot be set on a mergedFlavor directly.
versionNameOverride can instead be set for variant outputs using the following syntax:
android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.versionNameOverride = "1.0.0"
        }
    }
}

Attempt 3 (using ApplicationVariant object) instead:

So let's change our implementation to be like this

    applicationVariants.all(object : Action<com.android.build.gradle.api.ApplicationVariant> {
        override fun execute(variant: com.android.build.gradle.api.ApplicationVariant) {
            println("variant: ${variant}")
            variant.outputs.all(object : Action<com.android.build.gradle.api.BaseVariantOutput> {
                override fun execute(output: com.android.build.gradle.api.BaseVariantOutput) {

                    if (variant.buildType.name != "release") {
                    (output as com.android.build.gradle.internal.api.ApkVariantOutputImpl)
                            .versionNameOverride = "prefix-${variant.versionName}"
                    }
                }
            })
        }
    })

This whole approach, inspired by @david-mihola answer. He explained that groovy has its own magic here.

And if you want to change the APK name for each different buildTypes or productFlavors you can go to @david-mihola answer here.

like image 40
mochadwi Avatar answered Sep 28 '22 08:09

mochadwi


Build Type should override the Product Flavor. Try next one.

buildTypes {

    release {
        versionName = android.defaultConfig.versionName
    }
}
like image 1
Sergii Pechenizkyi Avatar answered Sep 28 '22 08:09

Sergii Pechenizkyi