自动增加VersionCode与gradle额外的属性


121

我正在使用gradle构建一个Android应用。到目前为止,我一直使用清单文件来增加versionCode,但是我想从外部文件中读取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'
}

在这里查看我的答案:stackoverflow.com/a/33637600/348189
TacB0sS 2015年

:另一种选择(一套和忘记的办法)medium.com/@passsy/...
西蒙B.

与您选择Gradle插件一起使用的一线工具:stackoverflow.com/a/61718437/4548500
SUPERCILEX

Answers:


207

我想从外部文件中读取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
}

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

这段代码只是在每个构建版本上颠覆了版本代码-您将需要扩展该技术来处理每个版本的版本代码。

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


4
如何仅在进行发行版本构建时启用此版本递增?
Piotr 2014年

@Piotr:如果您的意思是“仅增加发行版中的数字”,那应该是可能的,尽管我不知道细节。就个人而言,由于大约有20亿个版本代码可用,因此我假设我不会用完。:-)
CommonsWare,2014年

3
@Piotr,您将创建一个任务,该任务单独增加版本代码,然后执行类似assembleRelease.finalizedBy incrementVersion或类似的操作。整理后,我将发布我的代码。
克里斯·詹金斯(Chris.Jenkins)2014年

使用自定义任务,您可以执行类似的操作./gradlew incrementVersionCode build。一旦任何任务失败,以这种方式顺序调用的任务将立即停止。
2016年

3
由于@ chris.jenkins仍然在讲他的代码:p这是上面的任务和方法表格gist.github.com/doridori/544c24509be236c11fd5,可在android DSL内部使用versionCode getIncrementingVersionCode()
Dori,

83

这是我先前回答的现代化,可以在下面看到。这是与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

主要版本:必须手动更改以进行较大的更改。

次版本:必须手动更改,以免稍作改动。

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

构建版本:增加每个构建

版本号:补丁版本相同,这是Play商店每次上传新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 {
        ...
    }
}

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

初始答案:

我也希望versionName也自动增加。因此,这只是对CommonsWare的回答的补充,后者对我来说非常有效。这对我有用

defaultConfig {
    versionCode code
    versionName "1.1." + code
    minSdkVersion 14
    targetSdkVersion 18
}

编辑:

由于有点懒,我希望我的版本控制尽可能自动地工作。我想要的是一个随版本而增加的版本,而版本号版本名称仅在进行发行版本时才增加。

这是我过去一年一直使用的内容,其基础知识来自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!")
    }

    ...
}

...

如果您通过带有'assemble''assembleRelease''aR'的终端组装项目,则会在项目根目录中创建一个名为apk / RELEASE的新文件夹,从而增加了Patch和versionCode ,因此您无需查看构建/输出/ more / more / more查找您的apk。

您的版本属性应如下所示:

VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1

显然从0开始。


2
可以删除第二个'variant.outputs.each {output->',以及相应的'}'。
redocoder

这导致我所有的构建都只能使用x86_64本机代码
Chisko '17

@ Chisko我怀疑这段gradle代码是原因。提出一个新问题并分享您的gradle代码,我们可以尝试找出问题所在。:)
just_user

1
我现在可以确认这不是根本原因。我很抱歉。
奇斯科(Chisko)'17

1
@AlexanderGavriliuk是Play商店使用的版本代码,每次上传时都需要不断增加版本代码。如果增加主要版本或次要版本,补丁号可能会被重置。如果您使用相同的程序包名称将应用程序上载到Play商店,则版本号永远不应该重设。
just_user19年

40

如果不存在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
}

如果版本文件不存在,创建版本文件的位置在哪里?
portfoliobuilder

4
if(versionPropsFile.exists())确保文件不存在时不会爆炸。versionProps.store(versionPropsFile.newWriter(), null) 覆盖文件,无论它是否已经存在。
保罗·坎特雷尔

只好检查?:Groovy的含义。该Elvis操作符是三元运算符的缩短。
丹尼尔(Daniel)

30

我研究了一些方法来执行此操作,最终决定只使用当前时间作为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
    }
}

但是,如果您希望在2696年之后上传构建版本,则可能要使用其他解决方案。


2
如果您现在正在阅读1510351294
此书

我不明白!您是否不使用Analytics(分析)或crashlytics(崩溃分析)或任何其他提供带有版本代码和名称的数据的服务?而您正在轻松地玩这些游戏吗?
阿米尔·齐亚拉蒂

如果您有合理的版本名称,我认为很好。Crashalytics也提供版本名称。
netcyrax

@emmby您从何处获得“ 1451606400”号码?或#Entreco的'1510351294'我一直试图徒劳地计算!
Joseph Wambura

18

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

  1. versionCode在任何计算机(包括a Continuous Integration和/或Continuous Deployment服务器)上自动一致地生成。
  2. 与此相关的应用versionCode可提交给GooglePlay。
  3. 不依赖回购之外的任何文件。
  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
}

注意:为使此方法起作用,最好仅从同一分支机构(例如master)部署到Google Play商店。


从本质上讲,这是一个优雅的解决方案,我可以想象,这将大大降低构建时间,具体取决于2个git行中到底发生了什么。有什么经验吗?
HopefulHelpful

1
如果禁用此步骤,我不会发现任何性能改进。在本地和我们的构建机器上使用方法已有一年多了,性能从来都不是问题。如果您确实发现任何性能问题,请告诉我!
C0D3LIC1OU5

当您的解决方案很优雅时,它可能会给您带来令人讨厌的意外惊喜。至关重要的是,versionCodes必须始终大于以前的版本。如果您有一个分支具有50个提交,然后又创建了一个较新但只有40个提交的分支,那可能是由于从某些合并功能中挤压了多个提交所致。我可以看到很多原因,您的提交历史记录并不总是线性的增量提交流。
JHH

@JHH这些结果并不意外。正如我在注释中提到的那样,从同一分支进行部署时,此方法最有效。
C0D3LIC1OU5


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
}

从2022年1月1日开始formattedDate = date.format('yyMMddHHmm')超出了Integer的容量


1
这个人想要一个自动递增的内部版本号
peter_pilgrim

6
@peter_pilgrim Caro是OP。
马修(Matthew)阅读

我认为这是一个不错的解决方案,它不依赖于可能消失或不会消失或会不断出现在git中的文件。它还可以帮助您至少在接下来的22年中唯一地标识每个构建。
HopefulHelpful

引用developer.android.com:"Warning:最大的价值谷歌播放允许的versionCode是2100000000.“所以,截止实际上是2021年
部份

修正了整数限制:省略分钟并使用日期格式'yyMMddHH',版本代码将至少包含几个小时。
指针为空,

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
    }

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

档案 version.properties

VERSION_CODE=8


而是将其放在任务中,并使generateReleaseBuildConfig依赖于该任务。
拉各斯2015年

versionName“ 1.0。” + getSvnRevision()导致错误。getSvnRevision()方法在哪里引用?您确定它不应该是versionName“ 1.0。” +代码(版本名称会随您的版本代码增加)吗?
portfoliobuilder

1
@portfoliobuilder,将getSvnRevision()替换为代码
NickUnuchek 2015年

3

建立档案 version.properties

MAJOR=1
MINOR=3
PATCH=6
VERSION_CODE=1

变更build.gradle

android {
def _versionCode=0
def _major=0
def _minor=0
def _patch=0

def _applicationId = "com.example.test"

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==99)
    {
        _patch=0
        _minor=_minor+1
    }
    if(_major==99){
        _major=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}.${_versionCode}.${_minor}.${_patch}"


compileSdkVersion 23
buildToolsVersion "23.0.3"

defaultConfig {
    applicationId _applicationId
    minSdkVersion 11
    targetSdkVersion 23
    versionCode _versionCode
    versionName _versionName
}

}

输出: 1.1.3.6


谢谢。以及为什么要在versionName中插入一个versionCode?即使在第二位置。
CoolMind

但例如,它将看起来像1.71.3.76。我认为最好将1.3.76与版本代码分开。
CoolMind

是的。您可以更改为“ $ {_ major} .. $ {_ minor}。$ {_ patch}。$ {_ versionCode}”或删除补丁
Ahmad Aghazadeh

if(_major == 99)应该是if(_minor == 99)??
Anirudh Bagri

2

定义的versionNameAndroidManifest.xml

android:versionName="5.1.5"

在应用程序级别的内部android{...}build.gradle

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

应用程序级别的外部android{...}阻止build.gradle

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
}

创建了APK之后:

android:versionName="5.1.6"

注意:如果您的versionName与my不同,则需要更改则 regex提取零件逻辑


1

上面显示的示例由于不同的原因而无法正常工作

这是我根据本文的想法准备的即用型:

android {
    compileSdkVersion 28

    // /programming/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

归功于CommonsWare(接受的答案)Paul Cantrell(如果文件不存在,则创建文件)ahmad aghazadeh(版本名称和代码)

所以我将他们所有的想法融合在一起,并提出了这个想法。这是第一个帖子要求的拖放解决方案。

它将根据发行状态自动更新versionCode和versionName。当然,您可以移动变量以适应您的需求。

def _versionCode=0
def versionPropsFile = file('version.properties')
def Properties versionProps = new Properties()
if(versionPropsFile.exists())
    versionProps.load(new FileInputStream(versionPropsFile))
    def _patch = (versionProps['PATCH'] ?: "0").toInteger() + 1
    def _major = (versionProps['MAJOR'] ?: "0").toInteger()
    def _minor = (versionProps['MINOR'] ?: "0").toInteger()
    List<String> runTasks = gradle.startParameter.getTaskNames();
    def value = 0
    for (String item : runTasks)
        if ( item.contains("assembleRelease")) {
            value = 1;
        }
    _versionCode = (versionProps['VERSION_CODE'] ?: "0").toInteger() + value
    if(_patch==99)
    {
        _patch=0
        _minor=_minor+1
    }
    if(_major==99){
        _major=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)
def _versionName = "${_major}.${_versionCode}.${_minor}.${_patch}"

compileSdkVersion 24
buildToolsVersion "24.0.0"

defaultConfig {
    applicationId "com.yourhost.yourapp"
    minSdkVersion 16
    targetSdkVersion 24
    versionCode _versionCode
    versionName _versionName
}

0

使用Gradle Task Graph,我们可以检查/切换构建类型。

基本思想是在每个版本上增加versionCode。在每个构建一个计数器,该计数器存储在version.properties文件中。它将在每个新的APK构建上保持更新,并使用此递增的计数器值替换build.gradle文件中的versionCode字符串。

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'
}

将以上脚本放入主模块的build.gradle文件中。

参考网站: http : //devdeeds.com/auto-increment-build-number-using-gradle-in-android/

感谢和问候!


0

在每个“ Rebuild Project”时,“ First Commented”代码将递增数字,并将该值保存在“ Version Property”文件中。

在“构建APK”时,“第二条注释代码”将生成APK文件的新版本名称。

android {
    compileSdkVersion 28
    buildToolsVersion "29.0.0"
    //==========================START==================================
    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)
    //===========================END===================================
    defaultConfig {
        applicationId "com.example.myapp"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "0.19"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            //=======================================START===============================================
            android.applicationVariants.all { variant ->
                variant.outputs.all {
                    def appName = "MyAppSampleName"
                    outputFileName = appName+"_v${variant.versionName}.${versionProps['VERSION_CODE']}.apk"
                }
            }
            //=======================================END===============================================
        }
    }
}

请添加一些文字,显示您所做的更改。以及原因
马修·凯里安

0

在Mac上的Gradle 5.1.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.getStartParameter().getTaskRequests().toString()

    if (runTasks.contains('assemble') || runTasks.contains('assembleRelease') || runTasks.contains('aR')) {
        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 {
        applicationId "de.evomotion.ms10"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode versionNumber
        versionName "${versionMajor}.${versionMinor}.${versionPatch} (${versionBuild})"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        signingConfig signingConfigs.debug
    }

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

代码来自@just_user 这个


0

我真的很喜欢两种解决方案。第一个取决于Play商店,另一个取决于Git。

使用Play商店,您可以通过查看可用的最高上传版本代码来增加版本代码。此解决方案的优势在于,APK的上传不会失败,因为您的版本代码始终比Play商店上的版本代码高一个。不利之处在于,在Play商店之外分发APK变得更加困难。您可以按照快速入门指南并告诉插件自动解析版本代码,使用Gradle Play Publisher进行设置:

plugins {
    id 'com.android.application'
    id 'com.github.triplet.play' version 'x.x.x'
}

android {
    ...
}

play {
    serviceAccountCredentials = file("your-credentials.json")
    resolutionStrategy = "auto"
}

使用Git,您可以根据存储库中的提交和标记数量来增加版本代码。这样做的好处是您的输出是可复制的,并且不依赖于回购之外的任何东西。缺点是您必须进行新的提交或标记才能更改版本代码。您可以通过添加Version Master Gradle插件来进行设置

plugins {
    id 'com.android.application'
    id 'com.supercilex.gradle.versions' version 'x.x.x'
}

android {
    ...
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.