Autoincrement VersionCode mit zusätzlichen Eigenschaften

121

Ich baue eine Android App mit gradle. Bisher habe ich die Manifest-Datei verwendet, um den versionCode zu erhöhen, aber ich möchte den versionCode aus einer externen Datei lesen und je nachdem, ob es sich um die Release-Version oder die Debug-Version handelt, den versionCode erhöhen. Ich habe die zusätzlichen Eigenschaften ausprobiert, aber Sie können sie nicht speichern, was bedeutet, dass ich beim nächsten Erstellen denselben Versionscode erhalte. Jede Hilfe wäre sehr dankbar!

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'
}
Carvaq
quelle
Siehe meine Antwort hier: stackoverflow.com/a/33637600/348189
TacB0sS
Eine weitere Option (ein Set-and-Forget-Ansatz): medium.com/@passsy/…
Simon B.
Einzeiler
SUPERCILEX

Antworten:

206

Ich möchte den versionCode aus einer externen Datei lesen

Ich bin sicher, dass es eine Reihe möglicher Lösungen gibt. Hier ist eine:

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
}

Dieser Code erwartet eine vorhandene version.propertiesDatei, die Sie vor dem ersten Build von Hand erstellen würden VERSION_CODE=8.

Dieser Code stößt einfach den Versionscode bei jedem Build an - Sie müssten die Technik erweitern, um Ihren Versionscode pro Geschmack zu verarbeiten.

Sie können das Beispielprojekt für die Versionierung sehen, das diesen Code demonstriert.

CommonsWare
quelle
4
Wie kann ich diese Version nur inkrementieren, während Release-Builds erstellt werden?
Piotr
@Piotr: Wenn du meinst "nur die Anzahl bei einem Release-Build erhöhen", sollte das möglich sein, obwohl ich die Details nicht kenne. Persönlich gehe ich davon aus, dass mir nicht ausgehen wird, da ~ 2 Milliarden Versionscodes verfügbar sind. :-)
CommonsWare
3
@Piotr Sie würden eine Aufgabe erstellen, die den Versionscode separat erhöht und dann etwas Ähnliches assembleRelease.finalizedBy incrementVersionoder Ähnliches tut. Ich werde meinen Code veröffentlichen, sobald ich ihn aufgeräumt habe.
Chris.Jenkins
Mit einer benutzerdefinierten Aufgabe können Sie einfach so etwas tun ./gradlew incrementVersionCode build. Auf diese Weise nacheinander aufgerufene Aufgaben werden beendet, sobald eine der Aufgaben fehlschlägt.
Dori
3
Da @ chris.jenkins immer noch seinen Code ändert: p Hier ist die obige in Task- und Methodenform gist.github.com/doridori/544c24509be236c11fd5 , die innerhalb des Android DSL mitversionCode getIncrementingVersionCode()
Dori
83

Hier kommt eine Modernisierung meiner vorherigen Antwort, die unten zu sehen ist. Dieser läuft mit Gradle 4.4 und Android Studio 3.1.1 .

Was dieses Skript macht:

  • Erstellt eine version.properties- Datei, falls keine vorhanden ist (nach oben abstimmen Paul Cantrells Antwort unten, woher ich die Idee habe, wenn Ihnen diese Antwort gefällt)
  • Für jeden Build, jede Debug-Version oder jedes Mal, wenn Sie in Android Studio auf die Schaltfläche "Ausführen" klicken, erhöht sich die Anzahl VERSION_BUILD.
  • Jedes Mal, wenn Sie eine Version zusammenstellen , erhöht sich Ihr Android- Versionscode für den Play Store und Ihre Patch-Nummer .
  • Bonus: Nachdem der Build abgeschlossen ist, kopiere deine apk projectDir/apk, um sie zugänglicher zu machen.

Dieses Skript erstellt eine Versionsnummer, die aussieht, v1.3.4 (123)und erstellt eine APK- Datei wie AppName-v1.3.4.apk .

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

Hauptversion: Muss für größere Änderungen manuell geändert werden.

Nebenversion: Muss für etwas weniger große Änderungen manuell geändert werden.

Patch-Version: Erhöht sich beim Ausführengradle assembleRelease

Build-Version: Erhöht jeden Build

Versionsnummer: Wie bei der Patch-Version gilt dies für den Versionscode, den der Play Store für jeden neuen Apk-Upload erhöht haben muss.

Ändern Sie einfach den Inhalt in den Kommentaren mit den Bezeichnungen 1 - 3 unten, und das Skript sollte den Rest erledigen. :) :)

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

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

ERSTE ANTWORT:

Ich möchte, dass der Versionsname ebenfalls automatisch erhöht wird. Dies ist also nur eine Ergänzung zu der Antwort von CommonsWare, die für mich perfekt funktioniert hat. Das funktioniert bei mir

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

BEARBEITEN:

Da ich etwas faul bin, möchte ich, dass meine Versionierung so automatisch wie möglich funktioniert. Ich möchte eine Build-Version haben , die mit jedem Build zunimmt, während die Versionsnummer und der Versionsname nur zunehmen, wenn ich einen Release-Build erstelle.

Dies ist, was ich im letzten Jahr verwendet habe. Die Grundlagen stammen aus der Antwort von CommonsWare und meiner vorherigen Antwort sowie einigen weiteren. Dies führt zu folgender Versionierung:

Versionsname: 1.0.5 (123) -> Major.Minor.Patch (Build), Major und Minor werden manuell geändert.

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 und versionCode werden erhöht, wenn Sie Ihr Projekt über das Terminal mit 'assemble' , 'assembleRelease' oder 'aR' zusammenstellen , wodurch ein neuer Ordner in Ihrem Projektstamm mit dem Namen apk / RELEASE erstellt wird, sodass Sie nicht durch Build / Outputs schauen müssen / more / more / more um deine apk zu finden.

Ihre Versionseigenschaften müssten folgendermaßen aussehen:

VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1

Beginnen Sie natürlich mit 0. :)

just_user
quelle
2
Die zweite 'variante.outputs.each {output ->' kann mit dem entsprechenden '}' entfernt werden.
Redocoder
Dies führt dazu, dass alle meine Builds nur im nativen x86_64-Code enthalten sind
Chisko
@Chisko Ich bezweifle, dass dieser Teil des Gradle-Codes die Ursache ist. Stellen Sie eine neue Frage und teilen Sie Ihren Gradle-Code mit. Wir können versuchen, herauszufinden, was falsch ist. :)
just_user
1
Ich kann jetzt bestätigen, dass dies nicht die Grundursache war. Entschuldigen Sie.
Chisko
1
@AlexanderGavriliuk ist der Versionscode, der vom Play Store verwendet wird und der bei jedem Upload ständig erhöht werden muss. Die Patch-Nummer wird wahrscheinlich zurückgesetzt, wenn Sie die Haupt- oder Nebenversion erhöhen. Die Versionsnummer sollte niemals zurückgesetzt werden, wenn Sie die App mit demselben Paketnamen in den Play Store hochladen.
just_user
40

Eine leicht verschärfte Version der hervorragenden Antwort von CommonsWare erstellt die Versionsdatei, wenn sie nicht vorhanden ist:

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
}
Paul Cantrell
quelle
Wo ist der Teil über das Erstellen der Versionsdatei, wenn sie nicht existiert?
Portfoliobuilder
4
if(versionPropsFile.exists())stellt sicher, dass es nicht explodiert, wenn die Datei nicht vorhanden ist. versionProps.store(versionPropsFile.newWriter(), null) überschreibt die Datei unabhängig davon, ob sie bereits vorhanden ist.
Paul Cantrell
Musste überprüfen, was ?:in Groovy bedeutete. Der Elvis-Operator ist eine Abkürzung des ternären Operators.
Daniel
30

Ich habe mir einige Optionen dazu angesehen und letztendlich entschieden, dass es einfacher ist, nur die aktuelle Zeit für den versionCode zu verwenden, anstatt zu versuchen, den versionCode automatisch zu erhöhen und in mein Revisionskontrollsystem einzuchecken.

Fügen Sie Folgendes hinzu 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
    }
}

Wenn Sie jedoch erwarten, Builds über das Jahr 2696 hinaus hochzuladen, möchten Sie möglicherweise eine andere Lösung verwenden.

emmby
quelle
2
Wenn Sie dies jetzt lesen und mit einer neuen App beginnen, können Sie subtrahieren 1510351294:))
Entreco
Ich verstehe das nicht !! Verwenden Sie keine Analysen oder Crashlytics oder andere Dienste, die Daten mit Versionscodes und Namen bereitstellen? und du spielst so leicht damit?
Amir Ziarati
Wenn Sie vernünftige Versionsnamen haben, denke ich, ist es in Ordnung. Crashalytics geben auch den Versionsnamen an.
Netcyrax
@emmby Woher bekommen Sie die '1451606400'-Nummer? oder die '1510351294' von #Entreco Ich habe vergeblich versucht zu berechnen!
Joseph Wambura
18

Eine andere Möglichkeit, versionCodeautomatisch eine zu erhalten, besteht darin versionCode, die Anzahl der Commits in der ausgecheckten gitVerzweigung festzulegen. Es erreicht folgende Ziele:

  1. versionCodewird automatisch und konsistent auf jedem Computer (einschließlich eines Continuous Integrationund / oder Continuous DeploymentServers) generiert .
  2. App mit diesem kann versionCodean GooglePlay übermittelt werden.
  3. Verlässt sich nicht auf Dateien außerhalb von Repo.
  4. Schiebt nichts zum Repo
  5. Kann bei Bedarf manuell überschrieben werden

Verwenden der Gradle-Git- Bibliothek, um die oben genannten Ziele zu erreichen. Fügen Sie Ihrer build.gradleDatei im /appVerzeichnis den folgenden Code hinzu :

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
}

HINWEIS: Damit diese Methode funktioniert, sollten Sie sie nur aus demselben Zweig (z. B.) im Google Play Store bereitstellen master.

C0D3LIC1OU5
quelle
Obwohl es sich im Wesentlichen um eine elegante Lösung handelt, kann ich mir vorstellen, dass dies die Bauzeit drastisch verlangsamen würde, je nachdem, was genau in den 2 Git-Linien passiert. Irgendwelche Erfahrungen damit?
Hoffentlich
1
Ich bemerke keine Leistungsverbesserung, wenn dieser Schritt deaktiviert ist. Ich verwende die Methode seit über einem Jahr lokal und auf unseren Build-Maschinen und die Leistung war überhaupt kein Problem. Wenn Sie Leistungsprobleme bemerken, lassen Sie es mich wissen!
C0D3LIC1OU5
Während Ihre Lösung elegant ist, kann sie einige böse unerwartete Überraschungen bereiten. Es ist wichtig, dass versionCodes immer größer sind als in der vorherigen Version. Was ist, wenn Sie einen Zweig mit 50 Commits haben und dann einen anderen Zweig erstellen, der neuer ist, aber nur 40 Commits hat, möglicherweise weil mehrere Commits aus einer zusammengeführten Funktion entfernt wurden. Ich kann viele Gründe erkennen, warum Ihr Commit-Verlauf nicht immer ein linearer Strom inkrementeller Commits ist.
JHH
@JHH Diese Ergebnisse sind nicht unerwartet. Wie in einem Hinweis erwähnt, funktioniert diese Methode am besten, wenn sie von demselben Zweig aus bereitgestellt wird.
C0D3LIC1OU5
13

Vor kurzem arbeitete ich auf einem gradle Plugin für Android , das macht Erzeugung version und version automatisch. Es gibt viele Anpassungen. Hier finden Sie weitere Informationen dazu https://github.com/moallemi/gradle-advanced-build-version

Moallemi
quelle
Dies ist ein großartiges Plugin! Vielen Dank für das Teilen 🙂
Cory Robinson
10

Eine andere Option zum Inkrementieren von versionCodeund versionNameund ist die Verwendung eines Zeitstempels.

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
}

Ab Januar überschreitet 1 2022 formattedDate = date.format ('yyMMddHHmm') die Kapazität von Ganzzahlen

Carvaq
quelle
1
Die Person wollte eine Auto-Inkrement-Build-Nummer
peter_pilgrim
6
@ Peter_pilgrim Caro ist das OP.
Matthew Read
Ich denke, dies ist eine elegante Lösung. Sie basiert nicht auf Dateien, die möglicherweise verschwinden oder nicht oder die ständig in Git angezeigt werden. Es hilft Ihnen auch, jeden Build für mindestens das nächste Dutzend 22 Jahre eindeutig zu identifizieren.
Hoffentlich
Zitat von developer.android.com:"Warnung: Der größte Wert, den Google Play für versionCode zulässt, ist 2100000000. "Der Cutoff ist also tatsächlich 2021.
am
Fix für int limit: Minuten weglassen und Datumsformat 'yyMMddHH' verwenden, der Versionscode enthält mindestens Stunden.
Zeiger Null
10

Um versionCode nur in der Release-Version zu erhöhen, gehen Sie wie folgt vor:

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
    }

erwartet eine vorhandene c://YourProject/app/version.propertiesDatei, die Sie vor dem ersten Build von Hand erstellen würdenVERSION_CODE=8

Datei version.properties:

VERSION_CODE=8

NickUnuchek
quelle
Stellen Sie es lieber in eine Aufgabe und lassen Sie die generateReleaseBuildConfig von dieser Aufgabe abhängen.
Lagos
versionName "1.0." + getSvnRevision () verursacht einen Fehler. Wo verweist die Methode getSvnRevision ()? Sind Sie sicher, dass es nicht Versionsname "1.0" + Code sein sollte (der Versionsname erhöht sich mit Ihrem Versionscode)?
Portfoliobuilder
1
@portfoliobuilder, ersetzen Sie getSvnRevision () durch Code
NickUnuchek
3

Erstelle Datei version.properties

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

Änderung 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
}

}}

Ausgabe : 1.1.3.6

Ahmad Aghazadeh
quelle
Vielen Dank. Und warum haben Sie einen versionCode in versionName eingefügt? Auch an der zweiten Position.
CoolMind
Aber es wird zum Beispiel wie 1.71.3.76 aussehen. Ich denke, besser ist 1.3.76, es vom Versionscode zu trennen.
CoolMind
Ja . Sie können zu "$ {_ major} .. $ {_ minor}. $ {_ patch}. $ {_ versionCode}"
Ahmad Aghazadeh
if (_major == 99) sollte if (_minor == 99) sein ??
Anirudh Bagri
2

Definieren Sie versionName inAndroidManifest.xml

android:versionName="5.1.5"

Innerhalb des android{...}Blocks build.gradleder App-Ebene:

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

Außerhalb android{...}Block in build.gradleder App-Ebene:

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
}

Nach dem Erstellen der gesungenen APK:

android:versionName="5.1.6"

Hinweis: Wenn Ihre version anders als meine, müssen Sie ändern regex und Extrakt Teile Logik .

Sergey Shustikov
quelle
1

Die oben gezeigten Beispiele funktionieren aus verschiedenen Gründen nicht

Hier ist meine gebrauchsfertige Variante, die auf Ideen aus diesem Artikel basiert:

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

        ...
    }
...
}
Alexander Gavriliuk
quelle
0

Credits an CommonsWare (Akzeptierte Antwort) Paul Cantrell (Datei erstellen, falls nicht vorhanden) ahmad aghazadeh (Versionsname und Code)

Also habe ich all ihre Ideen zusammengebracht und mir das ausgedacht. Dies ist die Drag & Drop-Lösung für genau das, was im ersten Beitrag gefragt wurde.

Der Versionscode und der Versionsname werden automatisch entsprechend dem Versionsstatus aktualisiert. Natürlich können Sie die Variablen verschieben, um sie Ihren Anforderungen anzupassen.

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
}
Thunderstick
quelle
0

Mit Gradle Task Graph können wir den Build-Typ überprüfen / wechseln .

Die Grundidee besteht darin, den versionCode bei jedem Build zu erhöhen . Bei jedem Build wird ein Zähler in der Datei version.properties gespeichert. Es wird bei jedem neuen APK-Build auf dem neuesten Stand gehalten und ersetzt die versionCode- Zeichenfolge in der build.gradle- Datei durch diesen inkrementierten Zählerwert .

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

Platzieren Sie das obige Skript in Ihrer build.gradle-Datei des Hauptmoduls.

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

Danke & Grüße!

Jayakrishnan
quelle
0

Der zuerst kommentierte Code erhöht die Anzahl bei jedem "Projekt neu erstellen" und speichert den Wert in der Datei "Versionseigenschaft".

Der zweite kommentierte Code generiert beim Erstellen von APKs einen neuen Versionsnamen der APK-Datei.

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===============================================
        }
    }
}
Radha Krishna Eedulakanti
quelle
Bitte fügen Sie einen Text hinzu, der zeigt, was Sie geändert haben. und warum
Matthew Kerian
0

In der Gradle 5.1.1-Version auf Mac ive wurde geändert, wie die Aufgabennamen abgerufen wurden. Ich habe zwar versucht, den Build-Geschmack / -Typ aus dem Build zu ermitteln, war aber zu faul, um den Aufgabennamen aufzuteilen:

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

Code ist von @just_user dieser

Basur
quelle
0

Es gibt zwei Lösungen, die ich wirklich mag. Der erste hängt vom Play Store ab und der andere von Git.

Im Play Store können Sie den Versionscode erhöhen, indem Sie den höchsten verfügbaren hochgeladenen Versionscode anzeigen. Der Vorteil dieser Lösung ist, dass ein APK-Upload niemals fehlschlägt, da Ihr Versionscode immer um eins höher ist als der im Play Store. Der Nachteil ist, dass das Verteilen Ihrer APK außerhalb des Play Store schwieriger wird. Sie können dies mit Gradle Play Publisher einrichten, indem Sie der Kurzanleitung folgen und das Plugin , Versionscodes automatisch aufzulösen :

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

android {
    ...
}

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

Mit Git können Sie den Versionscode basierend auf der Anzahl der Commits und Tags in Ihrem Repository erhöhen. Der Vorteil hierbei ist, dass Ihre Ausgabe reproduzierbar ist und von nichts außerhalb Ihres Repos abhängt. Der Nachteil ist, dass Sie ein neues Commit oder Tag erstellen müssen, um Ihren Versionscode zu verbessern. Sie können dies einrichten, indem Sie das Version Master Gradle-Plugin hinzufügen :

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

android {
    ...
}
SUPERCILEX
quelle