Question

I'm trying to use Gradle to set app's name. Please, look at this snippet of build.gradle:

android {
    ...
    defaultConfig {
        ...
        versionCode getVersionCode()
        versionName getVersionName()
        ...
    }
    ...
}

...

int getVersionCode() {
    return 1
}

def getVersionName() {
    return "1.0"
}

Android Studio says

   'versionCode' cannot be applied to 'java.lang.Integer'
   'versionName' cannot be applied to 'java.lang.String'

and when I install the app on a device it has no versionCode and versionName at all.

The problem is clear to me but I don't know how to solve it.
Please advice.

Was it helpful?

Solution 2

EDITED

In order to define your app version dynamically, specify a custom method with def and call it, as such:

def computeVersionName() {
    return "2.0"
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.0"

    defaultConfig {
        versionCode 12
        versionName computeVersionName()
        minSdkVersion 16
        targetSdkVersion 16
    }
}

See here for more.

Make sure not to use function names that could conflict with existing getters in the given scope. For instance, defaultConfig { ... } calling getVersionName() will automatically use the getter defaultConfig.getVersionName() instead of the custom method.

OTHER TIPS

It doesn't resolve your issue, but it can be a different solution.

You can use gradle.properties inside your root project and define:

VERSION_NAME=1.2.1
VERSION_CODE=26

Then in your build.gradle you can use:

versionName project.VERSION_NAME
versionCode Integer.parseInt(project.VERSION_CODE)

Here is a build.gradle that I am using based on ideas from JakeWharton :

apply plugin: 'com.android.application'
def versionMajor = 1
def versionMinor = 2
def versionPatch = 0

def gitVersion() {
    def counter = 0
    def process = "git rev-list master --first-parent --count".execute()
    return process.text.toInteger()
}

repositories {
    mavenCentral()
}

android {
    compileSdkVersion 19
    buildToolsVersion '19.1.0'


    defaultConfig {
        applicationId 'my.project.com'
        minSdkVersion 14
        targetSdkVersion 19
        versionCode gitVersion()
        versionName "${versionMajor}.${versionMinor}.${versionPatch}"
    }
    ....
}

First of all - you are calling the inner getter., hence you have nulls.

versionCode property is accessed by getVersionCode().

versionName property is accessed by getVersionName()

So you get null and assign null... - remember, you are inside defaultConfig scope, hence Gradle will use the closest gerVersionCode() function.

There is a cleaner way to make it in newer Android Gradle (4.1.2).

Usually, those values are separated to the new file.

Firstly, you should use closures, not functions.

Fuction:

def myFunction() {

}

Closure:

myClosure = {

}

Also, you can extend ext scope (it is used to store all custom project-wide Gradle properties, this is a great place for it!) with your closure!

Remember not to name your functions 'getVersionName' 'getVersionCode'

Create a file config.gradle:

ext {
    appSetup = [
            majorVersion     : 1,
            minorVersion     : 0,
            patchVersion     : 0
    ]

    getAppVersionCode = { appSetup.majorVersion * 10000 + appSetup.minorVersion * 100 + appSetup.patchVersion }

    getAppVersionName = { "${appSetup.majorVersion}.${appSetup.minorVersion}.${appSetup.patchVersion}" }

In build.gradle:

// applies bloc
apply from: 'config.gradle'

android {
    versionCode getAppVersionCode()
    versionName getAppVersionName()

If you use a gradle.properties file to store shared build versions, make sur to use the toInteger() function for the version code, compiled/min and target sd versions.

See this post for more information: https://medium.com/@ali.muzaffar/gradle-configure-variables-for-all-android-project-modules-in-one-place-5a6e56cd384e#.yl1x0ziqe

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top