使用gradle额外属性自动增加VersionCode

car*_*vaq 112 android gradle build.gradle android-gradle-plugin

我正在用gradle构建一个Android应用程序.到目前为止,我使用Manifest文件来增加versionCode,但是我想从外部文件中读取versionCode,并且取决于它是发布风格还是调试风格增加了versionCode.我尝试了额外的属性,但是你无法保存它们,这意味着下次我构建它时我得到了相同的版本代码.任何帮助将非常感谢!

project.ext{
    devVersionCode = 13
    releaseVersionCode = 1
}

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.6.+'
    }
}

apply plugin: 'android'

repositories {
    mavenCentral()
}

dependencies {
    compile project(':Cropper')
    compile "com.android.support:appcompat-v7:18.0.+"
    compile "com.android.support:support-v4:18.0.+"
    compile fileTree(dir: 'libs', include: '*.jar')
}

def getReleaseVersionCode() {
    def version = project.releaseVersionCode + 1
    project.releaseVersionCode = version
    println sprintf("Returning version %d", version)
    return version
}

def getDevVersionCode() {
    def version = project.devVersionCode + 1
    project.devVersionCode = version
    println sprintf("Returning version %d", version)
    return version
}


def getLastVersioName(versionCode) {
    return "0.0." + versionCode
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.0"

    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 19
    }

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }
    }

    buildTypes {
        release {
            runProguard true
            proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
            proguardFile 'proguard.cfg'
            debuggable false
            signingConfig null
            zipAlign false
        }
        debug {
            versionNameSuffix "-DEBUG"
        }
    }
    productFlavors {
        dev {
            packageName = 'com.swisscom.docsafe.debug'
            versionCode getDevVersionCode()
            versionName getLastVersioName(project.devVersionCode)
        }
        prod {
            packageName = 'com.swisscom.docsafe'
            versionCode getReleaseVersionCode()
            versionName getLastVersioName(project.releaseVersionCode)
        }
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.8'
}
Run Code Online (Sandbox Code Playgroud)

Com*_*are 191

我想从外部文件中读取versionCode

我相信有很多可能的解决方案; 这是一个:

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
}
Run Code Online (Sandbox Code Playgroud)

此代码需要一个现有version.properties文件,您可以在第一次构建之前手动创建该文件VERSION_CODE=8.

这段代码简单地碰到了每个构建版本的代码 - 您需要扩展该技术来处理每个版本的代码.

您可以看到演示此代码的Versioning示例项目.

  • 如何在发布版本时启用此版本递增? (4认同)
  • @Piotr你会创建一个任务,单独增加版本代码,然后执行类似`assembleRelease.finalizedBy incrementVersion`或类似的东西.一旦我整理了它,我会发布我的代码. (3认同)
  • 由于@ chris.jenkins仍在使用他的代码:p以上是任务和方法形式https://gist.github.com/doridori/544c24509be236c11fd5,可以在android DSL内部使用`versionCode getIncrementingVersionCode()` (3认同)

jus*_*ser 74

这是我之前的答案的现代化,可以在下面看到.这个与Gradle 4.4Android Studio 3.1.1一起运行.

这个脚本做了什么:

  • 如果不存在,则创建一个version.properties文件(上面的投票Paul Cantrell的回答,如果你喜欢这个答案我就是这个想法)
  • 对于每个构建,调试版本或在Android Studio中按下运行按钮的任何时候,VERSION_BUILD编号都会增加.
  • 每次组装版本时,Play 版本的Android 版本代码都会增加,补丁编号也会增加.
  • 奖励:构建完成后,复制apk projectDir/apk以使其更易于访问.

此脚本将创建一个版本号,其外观v1.3.4 (123)和构建类似AppName-v1.3.4.apk的apk文件.

Major version ?       ? Build version
             v1.3.4 (123)
  Minor version ?|? Patch version
Run Code Online (Sandbox Code Playgroud)

主要版本:必须手动更改才能进行更大的更改.

次要版本:必须手动更改以获得稍微不那么大的更改.

补丁版本:运行时增加gradle assembleRelease

构建版本:增加每个构建

版本号:补丁版本相同,这适用于Play Store需要为每个新的apk上传增加的版本代码.

只需更改下面标有1 - 3的注释中的内容,脚本应该完成剩下的工作.:)

android {
    compileSdkVersion 27
    buildToolsVersion '27.0.3'

    def versionPropsFile = file('version.properties')
    def value = 0
    Properties versionProps = new Properties()
    if (!versionPropsFile.exists()) {
        versionProps['VERSION_PATCH'] = "0"
        versionProps['VERSION_NUMBER'] = "0"
        versionProps['VERSION_BUILD'] = "-1" // I set it to minus one so the first build is 0 which isn't super important. 
        versionProps.store(versionPropsFile.newWriter(), null)
    }

    def runTasks = gradle.startParameter.taskNames
    if ('assembleRelease' in runTasks) {
        value = 1
    }

    def mVersionName = ""
    def mFileName = ""

    if (versionPropsFile.canRead()) {
        versionProps.load(new FileInputStream(versionPropsFile))

        versionProps['VERSION_PATCH'] = (versionProps['VERSION_PATCH'].toInteger() + value).toString()
        versionProps['VERSION_NUMBER'] = (versionProps['VERSION_NUMBER'].toInteger() + value).toString()
        versionProps['VERSION_BUILD'] = (versionProps['VERSION_BUILD'].toInteger() + 1).toString()

        versionProps.store(versionPropsFile.newWriter(), null)

        // 1: change major and minor version here
        mVersionName = "v1.0.${versionProps['VERSION_PATCH']}"
        // 2: change AppName for your app name
        mFileName = "AppName-${mVersionName}.apk"

        defaultConfig {
            minSdkVersion 21
            targetSdkVersion 27
            applicationId "com.example.appname" // 3: change to your package name
            versionCode versionProps['VERSION_NUMBER'].toInteger()
            versionName "${mVersionName} Build: ${versionProps['VERSION_BUILD']}"
        }

    } else {
        throw new FileNotFoundException("Could not read version.properties!")
    }

    if ('assembleRelease' in runTasks) {
        applicationVariants.all { variant ->
            variant.outputs.all { output ->
                if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) {
                    outputFileName = mFileName
                }
            }
        }
    }

    task copyApkFiles(type: Copy){
        from 'build/outputs/apk/release'
        into '../apk'
        include mFileName
    }

    afterEvaluate {
        assembleRelease.doLast {
            tasks.copyApkFiles.execute()
        }
    }

    signingConfigs {
        ...
    }

    buildTypes {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

================================================== ==

初步答复:

我希望versionName也自动增加.所以这只是CommonsWare的答案的补充,它对我来说非常有用.这对我有用

defaultConfig {
    versionCode code
    versionName "1.1." + code
    minSdkVersion 14
    targetSdkVersion 18
}
Run Code Online (Sandbox Code Playgroud)

编辑:

因为我有点懒,我希望我的版本控制尽可能自动地工作.我想要的是拥有随每次构建而增加的构建版本,而版本号版本名称仅在我进行版本构建时增加.

这是我过去一年所使用的,基础知识来自CommonsWare的答案和我之前的答案,以及更多.这导致以下版本控制:

版本名称:1.0.5(123) - > Major.Minor.Patch(Build),Major和Minor都是手动更改的.

在build.gradle中:

...
android {
    compileSdkVersion 23
    buildToolsVersion '23.0.1'
    def versionPropsFile = file('version.properties')
    if (versionPropsFile.canRead()) {
        def Properties versionProps = new Properties()

        versionProps.load(new FileInputStream(versionPropsFile))

        def value = 0

        def runTasks = gradle.startParameter.taskNames
        if ('assemble' in runTasks || 'assembleRelease' in runTasks || 'aR' in runTasks) {
            value = 1;
        }

        def versionMajor = 1
        def versionMinor = 0
        def versionPatch = versionProps['VERSION_PATCH'].toInteger() + value
        def versionBuild = versionProps['VERSION_BUILD'].toInteger() + 1
        def versionNumber = versionProps['VERSION_NUMBER'].toInteger() + value

        versionProps['VERSION_PATCH'] = versionPatch.toString()
        versionProps['VERSION_BUILD'] = versionBuild.toString()
        versionProps['VERSION_NUMBER'] = versionNumber.toString()

        versionProps.store(versionPropsFile.newWriter(), null)

        defaultConfig {
            versionCode versionNumber
            versionName "${versionMajor}.${versionMinor}.${versionPatch} (${versionBuild}) Release"
            minSdkVersion 14
            targetSdkVersion 23
        }

        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                def fileNaming = "apk/RELEASES"
                variant.outputs.each { output ->
                    def outputFile = output.outputFile
                    if (outputFile != null && outputFile.name.endsWith('.apk')) {
                        output.outputFile = new File(getProject().getRootDir(), "${fileNaming}-${versionMajor}.${versionMinor}.${versionPatch}-${outputFile.name}")
                    }
                }
            }
        }

    } else {
        throw new GradleException("Could not read version.properties!")
    }

    ...
}

...
Run Code Online (Sandbox Code Playgroud)

如果您通过终端使用'assemble','assembleRelease''aR '组装项目,在项目根目录中创建一个名为apk/RELEASE的新文件夹,则增加Patch和versionCode ,这样您就不必查看构建/输出/更多/更多/更多来找到你的apk.

您的版本属性需要如下所示:

VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1
Run Code Online (Sandbox Code Playgroud)

显然从0开始.:)

  • 我似乎需要在 runTasks 中找到 `':app:assembleRelease'` 而不仅仅是 `'assembleRelease'`。 (3认同)
  • 第二个'variant.outputs.each {output - >'可以删除,相应的'}'. (2认同)
  • 我现在可以确认这不是根本原因。我很抱歉。 (2认同)

Pau*_*ell 36

如果版本文件不存在,CommonsWare的优秀答案会略微收紧版本:

def Properties versionProps = new Properties()
def versionPropsFile = file('version.properties')
if(versionPropsFile.exists())
    versionProps.load(new FileInputStream(versionPropsFile))
def code = (versionProps['VERSION_CODE'] ?: "0").toInteger() + 1
versionProps['VERSION_CODE'] = code.toString()
versionProps.store(versionPropsFile.newWriter(), null)

defaultConfig {
    versionCode code
    versionName "1.1"
    minSdkVersion 14
    targetSdkVersion 18
}
Run Code Online (Sandbox Code Playgroud)

  • if(versionPropsFile.exists())确保文件不存在时不会爆炸。versionProps.store(versionPropsFile.newWriter(),null)覆盖文件,而不管其是否已经存在。 (3认同)

emm*_*mby 26

我看了几个选项来做到这一点,并最终决定只使用versionCode的当前时间而不是尝试自动增加versionCode并将其检入我的版本控制系统更简单.

将以下内容添加到您的build.gradle:

/**
 * Use the number of seconds/10 since Jan 1 2016 as the versionCode.
 * This lets us upload a new build at most every 10 seconds for the
 * next 680 years.
 */
def vcode = (int)(((new Date().getTime()/1000) - 1451606400) / 10)

android {
    defaultConfig {
        ...
        versionCode vcode
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您希望上传超过2696年的版本,则可能需要使用其他解决方案.

  • 如果你现在正在阅读,并从一个新的应用程序开始,你可以减去`1510351294` :)) (2认同)

C0D*_*OU5 16

另一种versionCode自动获取方式是设置versionCode为已签出git分支中的提交数.它实现了以下目标:

  1. versionCode在任何计算机(包括Continuous Integration和/或Continuous Deployment服务器)上自动且一致地生成.
  2. 这个应用程序versionCode可以提交给GooglePlay.
  3. 不依赖于repo之外的任何文件.
  4. 不会向回购推送任何东西
  5. 如果需要,可以手动覆盖

使用gradle-git库来实现上述目标.将以下代码添加到您的build.gradle文件/app目录中:

import org.ajoberstar.grgit.Grgit

repositories {
    mavenCentral()
}

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'org.ajoberstar:grgit:1.5.0'
    }
}

android {
/*
    if you need a build with a custom version, just add it here, but don't commit to repo,
    unless you'd like to disable versionCode to be the number of commits in the current branch.

    ex. project.ext.set("versionCodeManualOverride", 123)
*/
    project.ext.set("versionCodeManualOverride", null)

    defaultConfig {
        versionCode getCustomVersionCode()
    }
}

def getCustomVersionCode() {

    if (project.versionCodeManualOverride != null) {
        return project.versionCodeManualOverride
    }

    // current dir is <your proj>/app, so it's likely that all your git repo files are in the dir
    // above.
    ext.repo = Grgit.open(project.file('..'))

    // should result in the same value as running
    // git rev-list <checked out branch name> | wc -l
    def numOfCommits = ext.repo.log().size()
    return numOfCommits
}
Run Code Online (Sandbox Code Playgroud)

注意:要使此方法有效,最好只从同一分支部署到Google Play商店(例如master).


moa*_*emi 12

最近我正在研究Android的gradle插件,它可以自动生成versionCodeversionName.有很多定制.在这里你可以找到更多关于它的信息 https://github.com/moallemi/gradle-advanced-build-version


car*_*vaq 10

另一个用于递增versionCode和的选项versionName是使用时间戳.

defaultConfig {
   versionName "${getVersionNameTimestamp()}"
   versionCode getVersionCodeTimestamp()
}


def getVersionNameTimestamp() {
    return new Date().format('yy.MM.ddHHmm')
}

def getVersionCodeTimestamp() {
    def date = new Date()
    def formattedDate = date.format('yyMMddHHmm')
    def code = formattedDate.toInteger()
    println sprintf("VersionCode: %d", code)
    return code
}
Run Code Online (Sandbox Code Playgroud)

从1月1日开始,formattedDate = date.format('yyMMddHHmm')超过了Integers的容量

  • @peter_pilgrim Caro是OP. (6认同)

Nic*_*hek 10

要仅在发行版本中增加versionCode,请执行以下操作:

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    def versionPropsFile = file('version.properties')
    def code = 1;
    if (versionPropsFile.canRead()) {
        def Properties versionProps = new Properties()

        versionProps.load(new FileInputStream(versionPropsFile))
        List<String> runTasks = gradle.startParameter.getTaskNames();
        def value = 0
        for (String item : runTasks)
        if ( item.contains("assembleRelease")) {
            value = 1;
        }
        code = Integer.parseInt(versionProps['VERSION_CODE']).intValue() + value
        versionProps['VERSION_CODE']=code.toString()
        versionProps.store(versionPropsFile.newWriter(), null)
    }
    else {
        throw new GradleException("Could not read version.properties!")
    }

    defaultConfig {
        applicationId "com.pack"
        minSdkVersion 14
        targetSdkVersion 21
        versionName "1.0."+ code
        versionCode code
    }
Run Code Online (Sandbox Code Playgroud)

需要一个现有的c://YourProject/app/version.properties文件,您可以在第一次构建之前手动创建该文件VERSION_CODE=8

档案 version.properties:

VERSION_CODE=8


Ahm*_*deh 6

在里面创建新文件 <yourProjectLocation>/app/version.properties

MAJOR=0
MINOR=0
PATCH=1
VERSION_CODE=1
Run Code Online (Sandbox Code Playgroud)

build.gradle(模块文件)中添加以下几行:

android {
    // other properties....
    // add following lines...

    def _versionCode=0
    def _major=0
    def _minor=0
    def _patch=0

    def versionPropsFile = file('version.properties')

    if (versionPropsFile.canRead()) {
        def Properties versionProps = new Properties()

        versionProps.load(new FileInputStream(versionPropsFile))

        _patch = versionProps['PATCH'].toInteger() + 1
        _major = versionProps['MAJOR'].toInteger()
        _minor = versionProps['MINOR'].toInteger() 
        _versionCode= versionProps['VERSION_CODE'].toInteger()+1
        
        if(_patch==100) {
            _patch=0
            _minor=_minor+1
        }
        if(_minor == 10){
            _minor = 0
            _major =_major + 1
        }

        versionProps['MAJOR']=_major.toString()
        versionProps['MINOR']=_minor.toString()
        versionProps['PATCH']=_patch.toString()
        versionProps['VERSION_CODE']=_versionCode.toString()
        versionProps.store(versionPropsFile.newWriter(), null)
    }
    else {
        throw new GradleException("Could not read version.properties!")
    }

    def _versionName = "${_major}.${_minor}.${_patch}(${_versionCode})"

    defaultConfig {
        // other properties...
        // change only these two lines

        versionCode _versionCode
        versionName _versionName
    }
}
Run Code Online (Sandbox Code Playgroud)

输出 : 0.0.1(1)


归档时间:

查看次数:

81362 次

最近记录:

6 年,2 月 前