Autoincrement VersionCode with gradle extra properties

前端 未结 16 2125
逝去的感伤
逝去的感伤 2020-11-27 08:47

I\'m building an Android app with gradle. Until now I used the Manifest file to increase the versionCode, but I would like to read the versionCode from an external file and

相关标签:
16条回答
  • 2020-11-27 09:41

    I would like to read the versionCode from an external file

    I am sure that there are any number of possible solutions; here is one:

    android {
        compileSdkVersion 18
        buildToolsVersion "18.1.0"
    
        def versionPropsFile = file('version.properties')
    
        if (versionPropsFile.canRead()) {
            def Properties versionProps = new Properties()
    
            versionProps.load(new FileInputStream(versionPropsFile))
    
            def code = versionProps['VERSION_CODE'].toInteger() + 1
    
            versionProps['VERSION_CODE']=code.toString()
            versionProps.store(versionPropsFile.newWriter(), null)
    
            defaultConfig {
                versionCode code
                versionName "1.1"
                minSdkVersion 14
                targetSdkVersion 18
            }
        }
        else {
            throw new GradleException("Could not read version.properties!")
        }
    
        // rest of android block goes here
    }
    

    This code expects an existing version.properties file, which you would create by hand before the first build to have VERSION_CODE=8.

    This code simply bumps the version code on each build -- you would need to extend the technique to handle your per-flavor version code.

    You can see the Versioning sample project that demonstrates this code.

    0 讨论(0)
  • 2020-11-27 09:43

    Using Gradle Task Graph we can check/switch build type.

    The basic idea is to increment the versionCode on each build. On Each build a counter stored in the version.properties file. It will be keep updated on every new APK build and replace versionCode string in the build.gradle file with this incremented counter value.

    apply plugin: 'com.android.application'
    
    android {
    compileSdkVersion 25
    buildToolsVersion '25.0.2'
    
    def versionPropsFile = file('version.properties')
    def versionBuild
    
    /*Setting default value for versionBuild which is the last incremented value stored in the file */
    if (versionPropsFile.canRead()) {
        def Properties versionProps = new Properties()
        versionProps.load(new FileInputStream(versionPropsFile))
        versionBuild = versionProps['VERSION_BUILD'].toInteger()
    } else {
        throw new FileNotFoundException("Could not read version.properties!")
    }
    
    
    /*Wrapping inside a method avoids auto incrementing on every gradle task run. Now it runs only when we build apk*/
    ext.autoIncrementBuildNumber = {
    
        if (versionPropsFile.canRead()) {
            def Properties versionProps = new Properties()
            versionProps.load(new FileInputStream(versionPropsFile))
            versionBuild = versionProps['VERSION_BUILD'].toInteger() + 1
            versionProps['VERSION_BUILD'] = versionBuild.toString()
            versionProps.store(versionPropsFile.nminSdkVersion 14
            targetSdkVersion 21
            versionCode 1ewWriter(), null)
        } else {
            throw new FileNotFoundException("Could not read version.properties!")
        }
    }
    
    
    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 21
        versionCode 1
        versionName "1.0.0." + versionBuild
    }
    
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    
    // Hook to check if the release/debug task is among the tasks to be executed.
    //Let's make use of it
    gradle.taskGraph.whenReady {taskGraph ->
        if (taskGraph.hasTask(assembleDebug)) {  /* when run debug task */
            autoIncrementBuildNumber()
        } else if (taskGraph.hasTask(assembleRelease)) { /* when run release task */
            autoIncrementBuildNumber()
        }
      }
    }
    
    dependencies {
      compile fileTree(dir: 'libs', include: ['*.jar'])
      compile 'com.android.support:appcompat-v7:25.3.1'
    }
    

    Place the above script inside your build.gradle file of main module.

    Reference Website: http://devdeeds.com/auto-increment-build-number-using-gradle-in-android/

    Thanks & Regards!

    0 讨论(0)
  • 2020-11-27 09:49

    Define versionName in AndroidManifest.xml

    android:versionName="5.1.5"
    

    Inside android{...} block in build.gradle of app level :

    defaultConfig {
            applicationId "com.example.autoincrement"
            minSdkVersion 18
            targetSdkVersion 23
            multiDexEnabled true
            def version = getIncrementationVersionName()
            versionName version
    }
    

    Outside android{...} block in build.gradle of app level :

    def getIncrementedVersionName() {
        List<String> runTasks = gradle.startParameter.getTaskNames();
    
        //find version name in manifest
        def manifestFile = file('src/main/AndroidManifest.xml')
        def matcher = Pattern.compile('versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\"').matcher(manifestFile.getText())
        matcher.find()
    
        //extract versionName parts
        def firstPart = Integer.parseInt(matcher.group(1))
        def secondPart = Integer.parseInt(matcher.group(2))
        def thirdPart = Integer.parseInt(matcher.group(3))
    
        //check is runTask release or not
        // if release - increment version
        for (String item : runTasks) {
            if (item.contains("assemble") && item.contains("Release")) {
                thirdPart++
                if (thirdPart == 10) {
                    thirdPart = 0;
                    secondPart++
                    if (secondPart == 10) {
                        secondPart = 0;
                        firstPart++
                    }
                }
            }
        }
    
        def versionName = firstPart + "." + secondPart + "." + thirdPart
    
        // update manifest
        def manifestContent = matcher.replaceAll('versionName=\"' + versionName + '\"')
        manifestFile.write(manifestContent)
    
        println "incrementVersionName = " + versionName
    
        return versionName
    }
    

    After create singed APK :

    android:versionName="5.1.6"
    

    Note : If your versionName different from my, you need change regex and extract parts logic.

    0 讨论(0)
  • 2020-11-27 09:51

    Examples shown above don't work for different reasons

    Here is my ready-to-use variant based on ideas from this article:

    android {
        compileSdkVersion 28
    
        // https://stackoverflow.com/questions/21405457
    
        def propsFile = file("version.properties")
        // Default values would be used if no file exist or no value defined
        def customAlias = "Alpha"
        def customMajor = "0"
        def customMinor = "1"
        def customBuild = "1" // To be incremented on release
    
        Properties props = new Properties()
        if (propsFile .exists())
            props.load(new FileInputStream(propsFile ))
    
        if (props['ALIAS'] == null) props['ALIAS'] = customAlias else customAlias = props['ALIAS']
        if (props['MAJOR'] == null) props['MAJOR'] = customMajor else customMajor = props['MAJOR']
        if (props['MINOR'] == null) props['MINOR'] = customMinor else customMinor = props['MINOR']
        if (props['BUILD'] == null) props['BUILD'] = customBuild else customBuild = props['BUILD']
    
        if (gradle.startParameter.taskNames.join(",").contains('assembleRelease')) {
            customBuild = "${customBuild.toInteger() + 1}"
            props['BUILD'] = "" + customBuild
    
            applicationVariants.all { variant ->
                variant.outputs.all { output ->
                    if (output.outputFile != null && (output.outputFile.name == "app-release.apk"))
                        outputFileName = "app-${customMajor}-${customMinor}-${customBuild}.apk"
                }
            }
        }
    
        props.store(propsFile.newWriter(), "Incremental Build Version")
    
        defaultConfig {
            applicationId "org.example.app"
            minSdkVersion 21
            targetSdkVersion 28
            versionCode customBuild.toInteger()
            versionName "$customAlias $customMajor.$customMinor ($customBuild)"
    
            ...
        }
    ...
    }
    
    0 讨论(0)
提交回复
热议问题