Incremento automatico VersionCode con gradle proprietà extra


121

Sto costruendo un'app Android con Gradle. Fino ad ora ho utilizzato il file Manifest per aumentare il versionCode, ma vorrei leggere il versionCode da un file esterno ea seconda che sia il gusto di rilascio o il gusto di debug aumentare il versionCode. Ho provato le proprietà extra, ma non puoi salvarle, il che significa che la prossima volta che lo creo ottengo lo stesso versionCode. Qualsiasi aiuto sarebbe molto apprezzato!

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

Vedere la mia risposta qui: stackoverflow.com/a/33637600/348189
TacB0sS

Un'altra opzione (un approccio imposta e dimentica): medium.com/@passsy/…
Simon B.

One-liner con la vostra scelta di Gradle plugins: stackoverflow.com/a/61718437/4548500
SUPERCILEX

Risposte:


207

Vorrei leggere il versionCode da un file esterno

Sono sicuro che ci siano innumerevoli soluzioni possibili; eccone uno:

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
}

Questo codice si aspetta un version.propertiesfile esistente , che creeresti a mano prima che abbia la prima build VERSION_CODE=8.

Questo codice sostituisce semplicemente il codice della versione su ogni build: è necessario estendere la tecnica per gestire il codice della versione per gusto.

Puoi vedere il progetto di esempio Controllo delle versioni che dimostra questo codice.


4
Come abilitare l'incremento di questa versione solo durante la creazione di build di rilascio?
Piotr

@Piotr: Se intendi "incrementare il numero solo in una build di rilascio", dovrebbe essere possibile, anche se non conosco i dettagli. Personalmente, poiché sono disponibili circa 2 miliardi di codici di versione, presumo che non finirò. :-)
CommonsWare

3
@ Piotr creeresti un'attività che incrementa separatamente il codice della versione, quindi fai qualcosa di simile assembleRelease.finalizedBy incrementVersiono qualcosa di simile. Inserirò il mio codice una volta che l'ho riordinato.
Chris.Jenkins

Usando un'attività personalizzata puoi semplicemente fare qualcosa di simile ./gradlew incrementVersionCode build. Le attività chiamate sequenzialmente in questo modo verranno interrotte non appena una delle attività non riesce.
Dori

3
Poiché @ chris.jenkins sta ancora comunicando il suo codice: p Ecco quanto sopra nel modulo di attività e metodo gist.github.com/doridori/544c24509be236c11fd5 che può essere utilizzato all'interno del DSL Android conversionCode getIncrementingVersionCode()
Dori

83

Ecco una modernizzazione della mia precedente risposta che può essere vista di seguito. Questo funziona con Gradle 4.4 e Android Studio 3.1.1 .

Cosa fa questo script:

  • Crea un file version.properties se non esiste (vota in alto la risposta di Paul Cantrell di seguito, da cui ho avuto l'idea se ti piace questa risposta)
  • Per ogni build, versione di debug o ogni volta che si preme il pulsante di esecuzione in Android Studio, il numero VERSION_BUILD aumenta.
  • Ogni volta che si organizza una versione Android versionCode per Play Store aumenta e il tuo numero di patch aumenta.
  • Bonus: al termine della compilazione copia il tuo apk in projectDir/apkper renderlo più accessibile.

Questo script creerà un numero di versione che assomiglia v1.3.4 (123)e costruirà un file apk come AppName-v1.3.4.apk .

Major version         Build version
             v1.3.4 (123)
  Minor version ⌃|⌃ Patch version

Versione principale: deve essere modificata manualmente per modifiche maggiori.

Versione secondaria: deve essere modificata manualmente per modifiche leggermente meno grandi.

Versione patch: aumenta durante l'esecuzionegradle assembleRelease

Versione build: aumenta ogni build

Numero versione: uguale alla versione patch , questo è per il codice della versione che Play Store deve aumentare per ogni nuovo caricamento di apk.

Basta cambiare il contenuto nei commenti etichettati 1 - 3 di seguito e lo script dovrebbe fare il resto. :)

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 {
        ...
    }
}

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

RISPOSTA INIZIALE:

Voglio che anche versionName aumenti automaticamente. Quindi questa è solo un'aggiunta alla risposta di CommonsWare che ha funzionato perfettamente per me. Questo è ciò che funziona per me

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

MODIFICARE:

Dato che sono un po 'pigro, voglio che il mio controllo delle versioni funzioni nel modo più automatico possibile. Quello che voglio è avere una versione build che aumenta con ogni build, mentre il numero di versione e il nome della versione aumentano solo quando creo una build di rilascio.

Questo è quello che ho usato nell'ultimo anno, le basi provengono dalla risposta di CommonsWare e dalla mia risposta precedente, più altre ancora. Ciò si traduce nel seguente controllo delle versioni:

Nome versione: 1.0.5 (123) -> Major.Minor.Patch (Build), Major e Minor vengono modificati manualmente.

In 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!")
    }

    ...
}

...

Patch e versionCode aumentano se assembli il tuo progetto tramite il terminale con 'assemble' , 'assembleRelease' o 'aR' che crea una nuova cartella nella root del tuo progetto chiamata apk / RELEASE in modo da non dover guardare attraverso build / output / more / more / more per trovare il tuo apk.

Le proprietà della tua versione dovrebbero assomigliare a questo:

VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1

Ovviamente inizia con 0. :)


2
Il secondo 'variant.outputs.each {output ->' può essere rimosso, con il corrispondente '}'.
redocoder

Questo fa sì che tutte le mie build siano solo in codice nativo x86_64
Chisko

@Chisko Dubito che questo pezzo del codice gradle sia la causa. Fai una nuova domanda e condividi il tuo codice gradle e possiamo provare a capire cosa non va. :)
just_user

1
Ora posso confermare che questa non era la causa principale. Mie scuse.
Chisko

1
@AlexanderGavriliuk è il codice di versione utilizzato dal Play Store che deve costantemente aumentare ad ogni caricamento. Il numero di patch verrà probabilmente ripristinato se aumenti la versione principale o secondaria. Il numero di versione non dovrebbe mai, non potrebbe mai essere reimpostato se carichi l'app nel Play Store con lo stesso nome di pacchetto.
just_user

40

Una versione leggermente rafforzata dell'eccellente risposta di CommonsWare crea il file di versione se non esiste:

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
}

dov'è la parte relativa alla creazione del file di versione se non esiste?
portfoliobuilder

4
if(versionPropsFile.exists())assicura che non esploda se il file non è presente. versionProps.store(versionPropsFile.newWriter(), null) sovrascrive il file indipendentemente dal fatto che esista già.
Paul Cantrell

Ho dovuto controllare cosa ?:significava in Groovy. L' operatore Elvis è un accorciamento dell'operatore ternario.
Daniel

30

Ho esaminato alcune opzioni per farlo e alla fine ho deciso che era più semplice usare solo l'ora corrente per versionCode invece di provare ad incrementare automaticamente versionCode e controllarlo nel mio sistema di controllo di revisione.

Aggiungi quanto segue al tuo 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
    }
}

Tuttavia, se prevedi di caricare build oltre l'anno 2696, potresti voler utilizzare una soluzione diversa.


2
Se stai leggendo questo ora e inizi con una nuova app, puoi sottrarre 1510351294:))
Entreco

non capisco !! non utilizzi analisi o crashlytics o altri servizi che forniscono dati con codici e nomi di versione? e stai giocando con questi facilmente?
Amir Ziarati

Se hai nomi di versione ragionevoli, penso che vada bene. Crashalytics fornisce anche il nome della versione.
netcyrax

@emmby da dove prendi il numero "1451606400"? o il '1510351294' di #Entreco che ho provato invano a calcolare!
Joseph Wambura

18

Un altro modo per ottenere versionCodeautomaticamente un è impostare versionCodeil numero di commit nel gitramo estratto . Realizza i seguenti obiettivi:

  1. versionCodeviene generato automaticamente e in modo coerente su qualsiasi macchina (inclusi un Continuous Integratione / o un Continuous Deploymentserver).
  2. L'app con questo versionCodeè inoltrabile a GooglePlay.
  3. Non si basa su file al di fuori del repository.
  4. Non invia nulla al repo
  5. Può essere sovrascritto manualmente, se necessario

Utilizzo della libreria gradle-git per raggiungere gli obiettivi di cui sopra. Aggiungi il codice sotto al tuo build.gradlefile nella /appdirectory:

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
}

NOTA: Affinché questo metodo funzioni, è meglio distribuirlo solo su Google Play Store dallo stesso ramo (es. master).


sebbene in sostanza una soluzione elegante, posso immaginare che questo rallenterebbe drasticamente il tempo di compilazione, a seconda di cosa sta accadendo esattamente nelle 2 linee git. Qualche esperienza su questo?
spera utile il

1
Non noto alcun miglioramento delle prestazioni se questo passaggio è disabilitato. Usiamo il metodo localmente e sulle nostre macchine di costruzione da oltre un anno e le prestazioni non sono state un problema di sorta. Se noti problemi di prestazioni, fammelo sapere!
C0D3LIC1OU5

Sebbene la tua soluzione sia elegante, potrebbe riservare brutte sorprese inaspettate. È fondamentale che i codici versione siano sempre più grandi rispetto alla versione precedente. Cosa succede se si dispone di un ramo con 50 commit e quindi si crea un altro ramo che è più recente ma ha solo 40 commit, forse a causa della compressione di un numero di commit da una funzione unita. Posso vedere molte ragioni per cui la cronologia dei tuoi commit non sarebbe sempre un flusso lineare di commit incrementali.
JHH

@JHH Questi risultati non sono inaspettati. Come accennato in una nota, questo metodo funziona meglio quando si distribuisce dallo stesso ramo.
C0D3LIC1OU5


10

Un'altra opzione, per incrementare il versionCodee il versionName, sta usando un timestamp.

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
}

A partire dal 1 gennaio 2022 formattedDate = date.format ('yyMMddHHmm') supera la capacità di numeri interi


1
La persona voleva un numero di build con incremento automatico
peter_pilgrim

6
@peter_pilgrim Caro è l'OP.
Matthew Read

Penso che questa sia una soluzione elegante, non si basa su file che potrebbero svanire o meno o che verranno visualizzati costantemente in git. Ti aiuta anche a identificare in modo univoco ogni build per almeno i prossimi 22 anni.
spera utile il

citando developer.android.com:"Warning: Il più grande valore di Google Play consente versionCode è 2100000000. "Così, il cut-off è in realtà 2021.
THS

Correzione del limite int: omettere i minuti e utilizzare il formato della data "aaMMggHH", il codice della versione conterrà almeno ore.
Pointer Null

10

Per incrementare versionCode solo nella versione di rilascio, farlo:

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
    }

si aspetta un esistente c://YourProject/app/version.properties file , che dovresti creare a mano prima che abbia la prima buildVERSION_CODE=8

File version.properties:

VERSION_CODE=8


Piuttosto inseriscilo in un'attività e fai in modo che generateReleaseBuildConfig dipenda da quell'attività.
lagos

versionName "1.0." + getSvnRevision () causa un errore. Dove fa riferimento il metodo getSvnRevision ()? Sei sicuro che non dovrebbe essere versionName "1.0." + Code (il nome della versione aumenterà con il codice della tua versione)?
portfoliobuilder

1
@portfoliobuilder, sostituisci getSvnRevision () nel codice
NickUnuchek

4

Crea file version.properties

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

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

}

Produzione : 1.1.3.6


Grazie. E perché hai inserito un versionCode in versionName? Anche in seconda posizione.
CoolMind

Ma ad esempio sarà 1.71.3.76. Penso che sia meglio 1.3.76, separandolo dal codice della versione.
CoolMind

Sì . puoi cambiare in "$ {_ major} .. $ {_ minor}. $ {_ patch}. $ {_ versionCode}" o rimuovere la patch
Ahmad Aghazadeh

if (_major == 99) dovrebbe essere if (_minor == 99) ??
Anirudh Bagri

2

Definisci versionName inAndroidManifest.xml

android:versionName="5.1.5"

android{...}Blocco interno a build.gradlelivello di app:

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

android{...}Blocco esterno a build.gradlelivello di app:

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
}

Dopo aver creato l'APK bruciato:

android:versionName="5.1.6"

Nota: se il tuo versionName è diverso dal mio, devi modificare la regex ed estrarre la logica delle parti .


1

Gli esempi mostrati sopra non funzionano per motivi diversi

Ecco la mia variante pronta per l'uso basata sulle idee di questo articolo:

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

Crediti a CommonsWare (Risposta accettata) Paul Cantrell (Crea file se non esiste) ahmad aghazadeh (Nome versione e codice)

Quindi ho mescolato tutte le loro idee e ho pensato a questo. Questa è la soluzione drag and drop per esattamente ciò che il primo post ha chiesto.

Aggiorna automaticamente versionCode e versionName in base allo stato del rilascio. Ovviamente puoi spostare le variabili in base alle tue esigenze.

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

Usando Gradle Task Graph possiamo controllare / cambiare il tipo di build.

L'idea di base è aumentare il versionCode su ogni build. In ogni build un contatore memorizzato nel file version.properties . Verrà aggiornato su ogni nuova build di APK e sostituirà la stringa versionCode nel file build.gradle con questo valore del contatore incrementato.

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

Posiziona lo script sopra nel file build.gradle del modulo principale.

Sito web di riferimento: http://devdeeds.com/auto-increment-build-number-using-gradle-in-android/

Grazie e saluti!


0

Il codice First Commented incrementerà il numero durante ogni "Rebuild Project" e salverà il valore nel file "Version Property".

Il secondo codice commentato genererà il nome della nuova versione del file APK mentre "Build APKs".

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

Aggiungi del testo che mostri cosa hai cambiato. e perché
Matthew Kerian

0

nella versione Gradle 5.1.1 su mac, ive ha cambiato il modo in cui i nomi delle attività venivano recuperati, anche se ho provato a ottenere il sapore / tipo di build dalla build ma ero troppo pigro per dividere il nome dell'attività:

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!")
}

il codice proviene da @just_user questo


0

Ci sono due soluzioni che mi piacciono molto. Il primo dipende dal Play Store e l'altro da Git.

Utilizzando il Play Store, puoi incrementare il codice della versione guardando il codice della versione caricato più alto disponibile . Il vantaggio di questa soluzione è che un caricamento di APK non fallirà mai poiché il codice della tua versione è sempre superiore a quello che si trova sul Play Store. Lo svantaggio è che la distribuzione del tuo APK al di fuori del Play Store diventa più difficile. Puoi configurarlo utilizzando Gradle Play Publisher seguendo la guida rapida e dicendo al plug-in di risolvere automaticamente i codici di versione :

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

android {
    ...
}

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

Utilizzando Git, puoi incrementare il codice della versione in base al numero di commit e tag di cui dispone il tuo repository. Il vantaggio qui è che il tuo output è riproducibile e non dipende da nulla al di fuori del tuo repository. Lo svantaggio è che devi fare un nuovo commit o tag per eseguire il bump del codice della versione. Puoi configurarlo aggiungendo il plug-in Version Master Gradle :

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

android {
    ...
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.