Gradle versionName and versionCode not working after 3.0 update - android

flavorDimensions "app"
productFlavors {
dev {
resValue "string", "base_url", "http://mydevurl/"
dimension "app"
}
prod {
resValue "string", "base_url", "http://myprodurl/"
dimension "app"
}
}
applicationVariants.all { variant ->
def flavor = variant.mergedFlavor
def versionName
if (variant.buildType.isDebuggable()) {
versionName = "debug_0.1.1"
}else{
versionName = "0.1.1"
}
flavor.versionName = versionName
flavor.versionCode = 50
}
Above gradle setup was working fine till Gradle 3.0 update. Couldn't find anything related in the website referred. How to manage this dynamic version control based on this new flavorDimension change?

You can dynamically set the versionCode and versionName with the 3.0 Android gradle plugin by using VariantOutput.setVersionCodeOverride() and VariantOutput.setVersionNameOverride().
For your project, this would look something like:
applicationVariants.all { variant ->
def flavor = variant.mergedFlavor
def versionName
if (variant.buildType.isDebuggable()) {
versionName = "debug_0.1.1"
}else{
versionName = "0.1.1"
}
flavor.versionName = versionName
flavor.versionCode = 50
variant.outputs.all { output ->
output.setVersionNameOverride(versionName)
output.setVersionCodeOverride(50)
}
}
reference: https://issuetracker.google.com/issues/63785806#comment6

Related

How to rename the app Bundle name from Android gradle with multiple product flavors?

As I was able to rename the APK using this way but could not get how to rename App Bundle with multiple flavors.
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
output.outputFileName = "${variant.getFlavorName()}-${variant.buildType.name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}-${output.getFilter(com.android.build.OutputFile.ABI)}.apk"
}
}
Here are my app flavors and split APK code
productFlavors {
aFlavor {
applicationId "com.a"
versionCode 5
versionName "1.0.5"
signingConfig signingConfigs.signingA
}
bFlavor {
applicationId "com.b"
versionCode 5
versionName "1.0.5"
signingConfig signingConfigs.signingB
}
cFlavor {
applicationId "com.c"
versionCode 3
versionName "1.0.3"
signingConfig signingConfigs.signingC
}
}
splits {
abi {
enable true
reset()
include 'arm64-v8a', 'x86', 'x86_64'
universalApk false
}
}
This is how I made and it works, try please
applicationVariants.all { variant ->
variant.outputs.all {
def flavor = variant.name
def versionName = variant.versionName
project.ext { appName = 'myApp' }
def formattedDate = new Date().format('dd-MM_HH-mm')
outputFileName = "${project.ext.appName}_${formattedDate}_v${versionName}_${flavor}.apk"
}
}

How to use productFlavors for android aab bundles

I try to build different Android app bundles via productFlavors. To keep and test the files I need a fixed file name.
For APK's I have the following working code:
applicationVariants.all { variant ->
if (variant.buildType.name.equals("release")) {
variant.outputs.all { output ->
outputFileName = "${applicationId}-${versionCode}-${variant.flavorName}.apk"
}
}
if (variant.getBuildType().isMinifyEnabled()) {
variant.assemble.doLast {
copy {
from variant.mappingFile
into variant.outputs[0].outputFile.parent
rename { String fileName ->
"${applicationId}-${versionCode}-${variant.flavorName}-mapping.txt"
}
}
}
}
}
But this don't work for bundles. I try to get it working with this code:
tasks.whenTaskAdded { task ->
if (task.name.startsWith("bundle")) {
def renameTaskName = "rename${task.name.capitalize()}Aab"
def flavor = task.name.substring("bundle".length()).uncapitalize()
tasks.create(renameTaskName, Copy) {
println android.defaultConfig.versionName
def applicationId = android.defaultConfig.applicationId
def versionCode = android.defaultConfig.versionCode
def path = "${buildDir}/outputs/bundle/${flavor}/"
from(path)
include "app.aab"
destinationDir file("${buildDir}/outputs/renamedBundle/")
rename "app.aab", "${applicationId}-${versionCode}-${flavor}.aab"
}
task.finalizedBy(renameTaskName)
}
}
But the version code is always the default version code. My build.gradle looks like this:
project.ext {
VERSION_CODE_INSTANT = 1150
VERSION_CODE_PLAY = 11500
VERSION_NAME = "1.1.5"
}
android {
defaultConfig {
applicationId "com.abc.test"
resValue "string", "app_name", "Test"
versionName VERSION_NAME
versionCode VERSION_CODE_PLAY
project.ext.set("archivesBaseName", "app");
}
productFlavors {
instant {
dimension 'type'
versionCode VERSION_CODE_INSTANT
}
play {
dimension 'type'
versionCode VERSION_CODE_PLAY
}
}
}
I also try to set project.ext.set("archivesBaseName", "app"); per flavour but this always generate the name of the play flavour. The Manifests inside the app bundles contains the correct versionCodes. How can I get the correct versionCode from the currently compiling flavour at the copy task?
Did you try to replace def versionCode = android.defaultConfig.versionCode by def versionCode = flavor.versionCode?
I think it meets your need.

Android different packageName with flavors

I need to install 2 versions of my project (Production and Development). I need 2 apps. I'm trying to achive it by using flavors, but when I sign the apk, it always generate the same app, with the same packageName (com.company.project). I've tried removing the applicationId from the defaultConfig but it doesn't work neither.In the manifest, the package name is com.company.project.
Anyone knows how to do that?
This is the build.gradle
defaultConfig {
multiDexEnabled true
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
applicationId "com.company.project"
}
productFlavors {
development {
applicationId
"com.company.project.DEV"
versionName "1.0-dev"
resValue "string", "app_name", "Project-Dev"
}
production {
applicationId
"com.company.project.PROD"
resValue "string", "app_name", "Project-Prod"
versionName "1.0-prod"
}
}
When you create productFlavors then the corresponding gradle tasks also changes.
For instance, originally you have only assembleDebug and assembleRelease. But, after implementing productFlavors, the gradle tasks will change. Taking your example in consideration, it will be
assembleDevelopmentDebug
assembleDevelopmentRelease
assembleProductionDebug
assembleProductionRelease
If you are using Android Studio, then you do not have to worry about the gradle tasks. Just select the Build Variant from the menu and build the project. It will run the corresponding gradle tasks and install the build.
I have written a blog explaining this, Product Flavors in Android. A sample project is also available on GitHub.
I'm doing a similar thing and my build.gradle looks like this and it works:
flavorDimensions 'Level'
productFlavors {
alpha {
dimension 'Level'
applicationIdSuffix '.alpha'
}
beta {
dimension 'Level'
applicationIdSuffix '.beta'
}
major {
dimension 'Level'
}
}
I actually set this up in Build -> Edit Flavors and it generated everything for me.
Finally I did it like this:
def appName = 'AppName'
productFlavors {
devel {
applicationIdSuffix ".devel"
def buildId, appNameLabel
buildId = androidApplicationId + '.devel' + androidVersionCode
appNameLabel = appName + 'd' + androidVersionName
buildConfigField "String", "BUILD_ID", '"' + buildId + '"'
manifestPlaceholders = [app_name_label: appNameLabel, buildId: buildId] }
QA {
applicationIdSuffix ".qa"
def buildId, appNameLabel
buildId = androidApplicationId + '.qa' + androidVersionCode
appNameLabel = appName + 'q' + androidVersionName
buildConfigField "String", "BUILD_ID", '"' + buildId + '"'
manifestPlaceholders = [app_name_label: appNameLabel, buildId: buildId]
}
pro {
buildConfigField "String", "BUILD_ID", '"' + androidApplicationId + '"'
manifestPlaceholders = [app_name_label: appName, buildId: androidApplicationId]
}

How do I include `applicationIdSuffix` in some generated resource value?

Imagine this setup:
android {
buildTypes {
debug {
applicationIdSuffix ".debug"
}
}
productFlavors {
foo {
applicationId defaultConfig.applicationId + '.foo'
}
}
}
How can I set up a dynamic string value such as
resValue "string", "package_name", applicationId
so that it includes the applicationIdSuffix for debug builds?
If I add this to defaultConfig, its my defaultConfig's applicationId that is set. If I add this to the flavor configuration, it is missing the applicationIdSuffix (this is null at this level).
Any hints?
The cool part about applicationIdSuffix is that you can use it in flavors as well as in build types. Check this out:
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "dev.bmax.suffixtext"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
applicationIdSuffix '.debug'
}
}
productFlavors {
prod {
applicationIdSuffix '.prod'
}
mock {
applicationIdSuffix '.mock'
}
}
}
Now, when I build my 'prodDebug' variant the final application ID is 'dev.bmax.suffixtext.prod.debug', which is what you want if I understand your question correctly.
EDIT
You can access the variant's name in a Gradle task like this:
applicationVariants.all { variant ->
// Use 'variant.name'
}
Gradle Android Plugin version 0.14.3 added support of the variant specific BuildConfigField/resValue:
applicationVariants.all { variant ->
variant.resValue "string", "name", "value"
}

Use different VersionCode for Debug/Release android gradle build

I'd like to apply different VersionCode to make apk file.
For debug only fix it to 1, and for release whatever number specified in defaultConfig.
Below code gives mypackage-release-1.apk file as assembleRelease artifact, which is not expected. I expected mypackage-release-10111.apk for that.
why the line debug { defaultConfig.versionCode=1 } affects assembleRelease artifact?
defaultConfig {
versionCode 10111
versionName '2.5.4'
minSdkVersion 10
targetSdkVersion 21
}
signingConfigs {
debug {
project.ext.loadSign = false
defaultConfig.versionCode = 1 // Why this value applied to assembleRelease?
}
release {
project.ext.loadSign = true
applicationVariants.all { variant ->
variant.outputs.each { output ->
def file = output.outputFile
output.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionCode + ".apk"))
}
}
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.release
}
}
Here's an updated version:
android {
defaultConfig { ... }
applicationVariants.all { variant ->
if (variant.name == 'debug') {
variant.outputs.each { output ->
output.versionCodeOverride = 1
}
}
}
}
Late on the party...
The entire gradle file evaluated before any task execution, so you are basically changing the default versionCode while declaring debug configs. There is no direct way to reset versionCode from buildType, but the link on the other answer do the trick by declaring a task on build variants.
android {
...
defaultConfig {
...
}
buildTypes {
...
}
applicationVariants.all { variant ->
def flavor = variant.mergedFlavor
def versionCode = flavor.versionCode
if (variant.buildType.isDebuggable()) {
versionCode += 1
}
flavor.versionCode = versionCode
}
}
The easiest solution is moving versionCode and versionName variables from defaultConfig to debug and release respectively.
android {
...
defaultConfig {
// without versionCode and versionName
...
}
buildTypes {
debug {
defaultConfig.versionCode X
defaultConfig.versionName 'X.Y.Z'
}
release {
defaultConfig.versionCode A
defaultConfig.versionName 'A.B.C'
}
}
...
}
Me too, but I think defaultConfig.versionCode was set when build.gradle be compiling. It's global static variable, and assigned at compiletime, not runtime.
I think we can intercept gradle task execution, and modify defaultConfig.versionCode at runtime.
After goooooooogle, I found this one works for me: https://gist.github.com/keyboardsurfer/a6a5bcf2b62f9aa41ae2
To use with Flavors:
applicationVariants.all { variant ->
def flavor = variant.mergedFlavor
def name = flavor.getVersionName()
def code = flavor.getVersionCode()
if (variant.buildType.isDebuggable()) {
name += '-d'
code = 1
}
variant.outputs.each { output ->
output.versionNameOverride = name
output.versionCodeOverride = code
}
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
if (variant.buildType.isDebuggable()) {
output.versionCodeOverride = 26
output.versionNameOverride = "2.2.6"
}
}
}
put it in android{}
So recently I had to deal with the same scenario and all the examples I could find use the applicationVariants property which is ill-documented imo.
So after some digging through the source code a bit, I realized that in the end versionCode and versionName properties from ProductFlavor get merged into the AndroidManifest which got me thinking: couldn't we just inject them by ourselves, cause we have manifestPlaceholders property on ProductFlavor AND on BuildType DSL objects, so I came up with this -- don't hesitate to give feedback and tell me why it's wrong
In build.gradle(app)
android {
...
buildTypes {
debug {
manifestPlaceholder = [versionCode: X, versionName: "X.Y.Z"]
}
release {
manifestPlaceholder = [versionCode: A, versionName: "A.B.C"]
}
}
...
}
In AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="..."
android:versionCode="${versionCode}"
android:versionName="${versionName}">
...
</manifest>

Categories

Resources