How to set versionName in APK filename using gradle?

95,002

Solution 1

This solved my problem: using applicationVariants.all instead of applicationVariants.each

buildTypes {
      release {
        signingConfig signingConfigs.release
        applicationVariants.all { variant ->
            def file = variant.outputFile
            variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk")) 
        }
    }       
}

Update:

So it seems this does not work with 0.14+ versions of android studio gradle plugin.

This does the trick (Reference from this question ) :

android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.outputFile = new File(
                    output.outputFile.parent,
                    output.outputFile.name.replace(".apk", "-${variant.versionName}.apk"))
        }
    }
}

Solution 2

I only have to change the version name in one place. The code is simple too.

The examples below will create apk files named named MyCompany-MyAppName-1.4.8-debug.apk or MyCompany-MyAppName-1.4.8-release.apk depending on the build variant selected.

Note that this solution works on both APK and App Bundles (.aab files).

See Also: How to change the proguard mapping file name in gradle for Android project

#Solution for Recent Gradle Plugin

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"
    defaultConfig {
        applicationId "com.company.app"
        minSdkVersion 13
        targetSdkVersion 21
        versionCode 14       // increment with every release
        versionName '1.4.8'   // change with every release
        setProperty("archivesBaseName", "MyCompany-MyAppName-$versionName")
    }
}

The above solution has been tested with the following Android Gradle Plugin Versions:

  • 3.6.4 (August 2020)
  • 3.5.2 (November 2019)
  • 3.3.0 (January 2019)
  • 3.1.0 (March 2018)
  • 3.0.1 (November 2017)
  • 3.0.0 (October 2017)
  • 2.3.2 (May 2017)
  • 2.3.1 (April 2017)
  • 2.3.0 (February 2017)
  • 2.2.3 (December 2016)
  • 2.2.2
  • 2.2.0 (September 2016)
  • 2.1.3 (August 2016)
  • 2.1.2
  • 2.0.0 (April 2016)
  • 1.5.0 (2015/11/12)
  • 1.4.0-beta6 (2015/10/05)
  • 1.3.1 (2015/08/11)

I'll update this post as new versions come out.

#Solution Tested Only on versions 1.1.3-1.3.0 The following solution has been tested with the following Android Gradle Plugin Versions:

  • 1.3.0 (2015/07/30) - Not Working, bug scheduled to be fixed in 1.3.1
  • 1.2.3 (2015/07/21)
  • 1.2.2 (2015/04/28)
  • 1.2.1 (2015/04/27)
  • 1.2.0 (2015/04/26)
  • 1.2.0-beta1 (2015/03/25)
  • 1.1.3 (2015/03/06)

app gradle file:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"
    defaultConfig {
        applicationId "com.company.app"
        minSdkVersion 13
        targetSdkVersion 21
        versionCode 14       // increment with every release
        versionName '1.4.8'   // change with every release
        archivesBaseName = "MyCompany-MyAppName-$versionName"
    }
}

Solution 3

(EDITED to work with Android Studio 3.0 and Gradle 4)

I was looking for a more complex apk filename renaming option and I wrote this one in the hope it is helpfull for anyone else. It renames the apk with the following data:

  • flavor
  • build type
  • version
  • date

It took me a bit of research in gradle classes and a bit of copy/paste from other answers. I am using gradle 3.1.3.

In the build.gradle:

android {

    ...

    buildTypes {
        release {
            minifyEnabled true
            ...
        }
        debug {
            minifyEnabled false
        }
    }

    productFlavors {
        prod {
            applicationId "com.feraguiba.myproject"
            versionCode 3
            versionName "1.2.0"
        }
        dev {
            applicationId "com.feraguiba.myproject.dev"
            versionCode 15
            versionName "1.3.6"
        }
    }

    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def project = "myProject"
            def SEP = "_"
            def flavor = variant.productFlavors[0].name
            def buildType = variant.variantData.variantConfiguration.buildType.name
            def version = variant.versionName
            def date = new Date();
            def formattedDate = date.format('ddMMyy_HHmm')

            def newApkName = project + SEP + flavor + SEP + buildType + SEP + version + SEP + formattedDate + ".apk"

            outputFileName = new File(newApkName)
        }
    }
}

If you compile today (13-10-2016) at 10:47, you get the following file names depending on the flavor and build type you have choosen:

  • dev debug: myProject_dev_debug_1.3.6_131016_1047.apk
  • dev release: myProject_dev_release_1.3.6_131016_1047.apk
  • prod debug: myProject_prod_debug_1.2.0_131016_1047.apk
  • prod release: myProject_prod_release_1.2.0_131016_1047.apk

Note: the unaligned version apk name is still the default one.

Solution 4

To sum up, for those don't know how to import package in build.gradle(like me), use the following buildTypes,

buildTypes {
      release {
        signingConfig signingConfigs.release
        applicationVariants.all { variant ->
            def file = variant.outputFile
            def manifestParser = new com.android.builder.core.DefaultManifestParser()
            variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile) + ".apk")) 
        }
    }       
}

===== EDIT =====

If you set your versionCode and versionName in your build.gradle file like this:

defaultConfig {
    minSdkVersion 15
    targetSdkVersion 19
    versionCode 1
    versionName "1.0.0"
}

You should set it like this:

buildTypes {   
        release {
            signingConfig signingConfigs.releaseConfig
            applicationVariants.all { variant ->
                def file = variant.outputFile
                variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
            }
        }
}


====== EDIT with Android Studio 1.0 ======

If you are using Android Studio 1.0, you will get an error like this:

Error:(78, 0) Could not find property 'outputFile' on com.android.build.gradle.internal.api.ApplicationVariantImpl_Decorated@67e7625f.

You should change the build.Types part to this:

buildTypes {
        release {
            signingConfig signingConfigs.releaseConfig
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    output.outputFile = new File(output.outputFile.parent, output.outputFile.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
                }
            }
        }
    }

Solution 5

If you don't specify versionName in defaultConfig block then defaultConfig.versionName will result in null

to get versionName from manifest you can write following code in build.gradle:

import com.android.builder.DefaultManifestParser

def manifestParser = new DefaultManifestParser()
println manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)
Share:
95,002

Related videos on Youtube

Coy
Author by

Coy

Updated on March 27, 2021

Comments

  • Coy
    Coy over 3 years

    I'm trying to set a specific version number in the gradle auto-generated APK filename.

    Now gradle generates myapp-release.apk but I want it to look something like myapp-release-1.0.apk.

    I have tried renaming options that seems messy. Is there a simple way to do this?

    buildTypes {
        release {
           signingConfig signingConfigs.release
           applicationVariants.each { variant ->
           def file = variant.outputFile
           variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" +    defaultConfig.versionName + ".apk"))
        }
    }
    

    I have tried the code above with no luck. Any suggestions? (using gradle 1.6)

  • Iwo Banas
    Iwo Banas over 10 years
    Do you know how to get it working if I have a versionName defined in AndroidManifest.xml instead of gradle config? It gives me myapp-release-null.apk now.
  • Ryan S
    Ryan S about 10 years
    I believe that with later versions of gradle, it is now com.android.builder.core.DefaultManifestParser
  • nasch
    nasch almost 10 years
    Anybody know how to do this if the version name is defined in the gradle file, but in the flavors rather than the defaultConfig?
  • Guy
    Guy almost 10 years
    This works great. However, since I increment my manifest version in the gradle build, it will create an APK with the older (pre-increment) value. Any way to make sure this takes affect after the gradle script increment the version number?
  • Wesley
    Wesley almost 10 years
    @Guy Sorry took so long. I edited the answer, see if it can solve your problem.
  • Argyle
    Argyle over 9 years
    This answer doesn't work with 0.14+ versions of the gradle plugin. Any updates to work with those?
  • withoutclass
    withoutclass over 9 years
    @Argyle you'd need to work with all the possible output files at once utilizing something like: variant.outputs.each { output -> output.setOutputFile(new File (file.parent, some_new_filename) }
  • Argyle
    Argyle over 9 years
    @withoutclass I asked this as it's own question and got it answered here: stackoverflow.com/questions/27068505/…
  • Martin
    Martin over 9 years
    Sorry does not work (any longer): No such property: archivesBaseName for class: org.gradle.api.internal.project.DefaultProject_Decorated
  • Marco RS
    Marco RS over 9 years
    What gradle version are you using?
  • Nandish A
    Nandish A about 9 years
    I think this is the right approach instead of writing another task to rename files.
  • ligi
    ligi almost 9 years
    just change to archivesBaseName = "MyCompany-MyAppName-$versionName" if you have OCD and do not want AS warn you about the +
  • Patrick
    Patrick almost 9 years
    this is scheduled to be deprecated in gradle 2+ see stackoverflow.com/a/20660274/774398
  • Jon
    Jon almost 9 years
    @for3st I'll soon update the answer with a gradle 2+ version which is setProperty("archivesBaseName", "MyCompany-MyAppName-$versionName")
  • Ewoks
    Ewoks almost 9 years
    can version name be set when build starts..? My goal would be to have auto generated versionName that will look like "1.4.8 (20150825_115958)".. Version 1.4.8 can be still set in gradle build file but timestamp would be assigned automatically. Generated apk would have same timestamp as suffix in file name like "MyApp_v1.4.8_20150825_115958" ..
  • Jon
    Jon almost 9 years
    @Ewoks def date = new Date().format('yyyyMMddHHmmss') and setProperty("archivesBaseName", "MyCompany-MyAppName-$versionName-$date") seem close to what you're asking for and while it seems to generate apk's with the date in the file name, android studio can't automatically install them, throwing Local path doesn't exist in my tests. I wonder why you want this in the first place as gradle builds, when used with git are repeatable. Having timestamps on a binary doesn't really tell me anything about the code used to generate it.
  • Ewoks
    Ewoks almost 9 years
    it tells my customer and it is easier for me to communicate with them when there is timestamp.. I found other way in the mean time but as you said Android Studio for some reason doesn't find that file
  • HeyZiko
    HeyZiko over 8 years
    I combined this answer with an auto-increment of version code SO answer (stackoverflow.com/a/25166200/1876622) so that I don't have to manually change each build number during development.
  • Amir Uval
    Amir Uval over 8 years
    This piece of code works, but it seem to trigger a bug in Android Studio that hangs the IDE when editing (on Linux). Another script that causes this: code.google.com/p/android/issues/detail?id=187493
  • Kerem
    Kerem over 8 years
    Putting setProperty("archivesBaseName", "MyCompany-MyAppName-$versionName") in your defaultConfigworks nicely with gradle:1.5.0 plugin.
  • Simon K. Gerges
    Simon K. Gerges about 8 years
    setProperty("archivesBaseName", "MyCompany-MyAppName-$versionName") works perfectlly with gradle:2.0.0, Many thanks
  • Mars
    Mars over 7 years
    Where are you setting the generated versionCode and versionName variables?
  • Igor Čordaš
    Igor Čordaš over 7 years
    As I remember that was done inside our custom gradle plugin. Its execution was called as last action of preBuild task.
  • Pabel
    Pabel over 7 years
    Great solution. I tried it, and it is perfect for my problem. Thanks!
  • Alessandro Caliaro
    Alessandro Caliaro over 7 years
    is it possible to use the same approach in Xamarin Studio?
  • Fer
    Fer over 7 years
    It would be great if it was possible, but I am starting right now a Xamarin course and I still haven't enough practice with it to know if it is possible or not. I will ask this question and come here again.
  • Fer
    Fer over 7 years
    Comment from the teacher of the course: "there is an option where you can use commands in order to change the name of the generated files". Therefore, the approach to use from Xamarin must be different to the one I wrote for Android Studio, sorry.
  • weston
    weston about 7 years
    Great find, but doesn't work well with flavors with different version codes. They all end up with same version code.
  • Tom
    Tom almost 7 years
    This doesn't change the APK filename.
  • PHPirate
    PHPirate over 6 years
    For people updating to Gradle 4: change each to all and output.outputFile to outputFileName. If somebody confims this works it can be edited into the answer :)
  • Upendra Shah
    Upendra Shah over 6 years
    is it possible to add a string from a class file to apk name??
  • Mooing Duck
    Mooing Duck over 6 years
    @PHPirate: almost works: Error:(34, 0) Cannot set the value of read-only property 'name'
  • PHPirate
    PHPirate over 6 years
    @MooingDuck Yeah sorry I was a bit vague, does the following work for you? Same as in answer but output -> def newName = outputFileName; newName.replace(".apk", "-${variant.versionName}.apk"); outputFileName = new File(newName)
  • PHPirate
    PHPirate over 6 years
    Or a bit simpified, output -> outputFileName = "${variant.name}-${variant.versionName}.apk". I added a new answer in which it looks much clearer.
  • Gene Bo
    Gene Bo over 6 years
    To resolve the error Cannot set the value of read-only property 'outputFile' - as mentioned in an earlier comment for having to "change each to all and output.outputFile to outputFileName " - this post provides some details on that: stackoverflow.com/a/44265374/2162226
  • Rosário Pereira Fernandes
    Rosário Pereira Fernandes over 6 years
    While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.
  • deLock
    deLock about 6 years
    Is there not any variable name for MyAppName? That seems odd. I mean the hardcoded string literals "MyCompany-MyAppName-$versionName"
  • strangetimes
    strangetimes about 6 years
    Doesn't work with Bundles, any update to make it work with bundles?
  • Fer
    Fer about 6 years
    I have edited the answer with this suggestion. Thanks @gnB
  • Netherdan
    Netherdan almost 6 years
    @deLock in case you or someone else is wondering - you can set the variable applicationName in the gradle.properties file and use it in the build.gradle like so: setProperty("archivesBaseName", "$applicationName-$versionName"). Or you can use the $applicationId variable
  • Droid Chris
    Droid Chris almost 6 years
    Nice one on this! I like this better then other ways I currently doing this.
  • Allan W
    Allan W over 5 years
    Is there any way to add variant.buildType.name to the name? I know this isn't really default config related, but I'm trying to figure out how to remove the obsolete variantOutput.getAssemble() warning
  • ilyamuromets
    ilyamuromets about 5 years
    Is it possible to remove from apk name last '-debug' / '-release'?
  • android developer
    android developer almost 5 years
    This is a nice tip, actually. Not in the right question, but good one. Where can I read more about it? Is it possible to use versionNameSuffix based on the GIT branch? For example, if it's not on "master", always have a suffix, even if it's a release version
  • Kellin Strook
    Kellin Strook about 4 years
    Excellent approach. Makes it easy to modify file output, especially when producing Split APKs.
  • spartygw
    spartygw about 4 years
    Looks like this broke again in gradle 6
  • spartygw
    spartygw about 4 years
    Any idea how to fix this for gradle 6?
  • Kirill Kostrov
    Kirill Kostrov over 3 years
    variant.variantData.variantConfiguration.buildType.name should be replaced with variant.buildType.name