web-dev-qa-db-fra.com

Comment créer automatiquement un code de version dans Android Gradle

J'expérimente avec le nouveau système de compilation Android basé sur Gradle et je me demande quel est le meilleur moyen de créer automatiquement versionCode avec. Je pense à deux options

  1. créer un fichier versionCode, en lire le numéro, l'augmenter et l'écrire dans le fichier
  2. analyser AndroidManifest.xml, en lire le code de version, l'augmenter et le réécrire dans le fichier AndroidManifest.xml

Existe-t-il une solution plus simple ou appropriée? 

Quelqu'un a-t-il utilisé l'une des options disponibles et pourrait-il le partager avec moi?

78
sealskej

J'ai décidé pour la deuxième option - d'analyser AndroidManifest.xml. Voici l'extrait de travail.

task('increaseVersionCode') << {
    def manifestFile = file("AndroidManifest.xml")
    def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcher = pattern.matcher(manifestText)
    matcher.find()
    def versionCode = Integer.parseInt(matcher.group(1))
    def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"")
    manifestFile.write(manifestContent)
}

tasks.whenTaskAdded { task ->
    if (task.name == 'generateReleaseBuildConfig') {
        task.dependsOn 'increaseVersionCode'
    }
}

versionCode est publié pour les versions validées dans ce cas. Pour l'augmenter pour les versions de débogage, changez l'équation task.name dans le rappel task.whenTaskAdded.

56
sealskej

J'utilise ce code pour mettre à jour à la fois versionCode et versionName, en utilisant un schéma "major.minor.patch.build".

import Java.util.regex.Pattern

task('increaseVersionCode') << {
    def manifestFile = file("src/main/AndroidManifest.xml")
    def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcher = pattern.matcher(manifestText)
    matcher.find()
    def versionCode = Integer.parseInt(matcher.group(1))
    def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"")
    manifestFile.write(manifestContent)
}

task('incrementVersionName') << {
    def manifestFile = file("src/main/AndroidManifest.xml")
    def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
    matcherVersionNumber.find()
    def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
    def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
    def pointVersion = Integer.parseInt(matcherVersionNumber.group(3))
    def buildVersion = Integer.parseInt(matcherVersionNumber.group(4))
    def mNextVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion + 1)
    def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"")
    manifestFile.write(manifestContent)
}

tasks.whenTaskAdded { task ->
    if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
        task.dependsOn 'increaseVersionCode'
        task.dependsOn 'incrementVersionName'
    }
}
39
Andres

cela ne semble pas être la configuration exacte que vous utilisez, mais dans mon cas, les versions sont gérées par jenkins et je voulais utiliser son code $ BUILD_NUMBER comme versionCode de l'application. ce qui suit a fait le tour pour moi là-bas.

defaultConfig {
    ...
    versionCode System.getenv("BUILD_NUMBER") as Integer ?: 9999
    ...
}
36
user2399268

J'utilise l'horodatage pour le code de version: 

def date = new Date()
def formattedDate = date.format('yyMMddHHmm')
def code = formattedDate.toInteger()

defaultConfig {
    minSdkVersion 10
    targetSdkVersion 21
    versionCode code
}
13
thanhbinh84

Si vous avez le code de version dans le fichier build.gradle, utilisez le prochain extrait:

import Java.util.regex.Pattern    
task('increaseVersionCode') << {
    def buildFile = file("build.gradle")
    def pattern = Pattern.compile("versionCode\\s+(\\d+)")
    def manifestText = buildFile.getText()
    def matcher = pattern.matcher(manifestText)
    matcher.find()
    def versionCode = Integer.parseInt(matcher.group(1))
    def manifestContent = matcher.replaceAll("versionCode " + ++versionCode)
    buildFile.write(manifestContent)
}
7
Elhanan Mishraky

Pour prendre en compte à la fois les types de produit et de génération de produit et utiliser la logique de @ sealskej pour l'analyse de manifeste:

Android.applicationVariants.all { variant ->
    /* Generate task to increment version code for release */
    if (variant.name.contains("Release")) {
        def incrementVersionCodeTaskName = "increment${variant.name}VersionCode"
        task(incrementVersionCodeTaskName) << {
            if (Android.defaultConfig.versionCode == -1) {
                def manifestFile = file(Android.sourceSets.main.manifest.srcFile)
                def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
                def manifestText = manifestFile.getText()
                def matcher = pattern.matcher(manifestText)
                matcher.find()
                def versionCode = Integer.parseInt(matcher.group(1))
                Android.defaultConfig.versionCode = versionCode + 1
                def manifestContent = matcher.replaceAll("versionCode=\"" + Android.defaultConfig.versionCode + "\"")
                manifestFile.write(manifestContent)
            }
        }
        def hookTask = variant.generateBuildConfig
        hookTask.dependsOn(incrementVersionCodeTaskName)
    }
}
4
Max Ch

Gradle Advanced Build Version est un plugin pour Android permettant de générer automatiquement versionCode et versionName. il y a beaucoup de personnalisation. Vous trouverez ici plus d’informations à ce sujet https://github.com/moallemi/gradle-advanced-build-version

4
moallemi

Incrémenter la tâche VersionCode (entier):

Cela fonctionne en incrémentant le code de version de 1, par exemple:

  Android:versionCode="1"
1 + 1 = 2
import Java.util.regex.Pattern

task incrementVersionCode << {
    def manifestFile = file('AndroidManifest.xml')
    def matcher = Pattern.compile('versionCode=\"(\\d+)\"')
    .matcher(manifestFile.getText())
    matcher.find()
    def manifestContent = matcher.replaceAll('versionCode=\"' +
        ++Integer.parseInt(matcher.group(1)) + '\"')
    manifestFile.write(manifestContent)
}

Incrémenter la tâche VersionName (chaîne):

Avertissement: Doit contenir 1 période pour Regex

Cela fonctionne en incrémentant le nom de version de 0.01, par exemple: Vous pouvez facilement modifier et modifier votre incrément ou ajouter d'autres chiffres.

Android:versionName="1.0"
1.00 + 0.01 -> 1.01
1.01 + 0.01 -> 1.02
1.10 + 0.01 -> 1.11
1.99 + 0.01 -> 2.0
1.90 + 0.01 -> 1.91
import Java.util.regex.Pattern

task incrementVersionName << {
    def manifestFile = file('AndroidManifest.xml')
    def matcher = Pattern.compile('versionName=\"(\\d+)\\.(\\d+)\"')
    .matcher(manifestFile.getText())
    matcher.find()
    def versionName = String.format("%.2f", Integer
        .parseInt(matcher.group(1)) + Double.parseDouble("." + matcher
            .group(2)) + 0.01)
    def manifestContent = matcher.replaceAll('versionName=\"' +
        versionName + '\"')
    manifestFile.write(manifestContent)
}

Avant:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
    package="com.exmaple.test"
    Android:installLocation="auto"
    Android:versionCode="1"
    Android:versionName="1.0" >

Après:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
    package="com.exmaple.test"
    Android:installLocation="auto"
    Android:versionCode="2"
    Android:versionName="1.01" >
3
Jared Burrows

Si vous écrivez votre versionCode dans le fichier gradle.build (la plupart des cas actuellement), voici une solution de contournement. Un peu stupide (mise à jour "self"), mais ça marche!

import Java.util.regex.Pattern

task('increaseVersionCode') << {
    def buildFile = file("build.gradle")
    def pattern = Pattern.compile("versionCode(\\s+\\d+)")
    def buildText = buildFile.getText()
    def matcher = pattern.matcher(buildText)
    matcher.find()
    def versionCode = Android.defaultConfig.versionCode
    def buildContent = matcher.replaceAll("versionCode " + ++versionCode)
    buildFile.write(buildContent)

    System.out.println("Incrementing Version Code ===> " + versionCode)
}

tasks.whenTaskAdded { task ->
    if (task.name == 'generateReleaseBuildConfig') {
        task.dependsOn 'increaseVersionCode'
    }
}
2
iStar

Pour ajouter au message de @ sealskej, voici comment vous pouvez mettre à jour votre code de version et votre nom de version (ici, je suppose que vos versions majeure et mineure sont toutes les deux 0):

task('increaseVersion') << {
    def manifestFile = file("AndroidManifest.xml")
    def patternVersionCode = Pattern.compile("versionCode=\"(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcherVersionCode = patternVersionCode.matcher(manifestText)
    matcherVersionCode.find()
    def versionCode = Integer.parseInt(matcherVersionCode.group(1))
    def manifestContent = matcherVersionCode.replaceAll("versionCode=\"" + ++versionCode + "\"")

    manifestFile.write(manifestContent)

    def patternVersionNumber = Pattern.compile("versionName=\"0.0.(\\d+)\"")
    manifestText = manifestFile.getText()
    def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
    matcherVersionNumber.find()
    def versionNumber = Integer.parseInt(matcherVersionNumber.group(1))
    manifestContent = matcherVersionNumber.replaceAll("versionName=\"0.0." + ++versionNumber + "\"")
    manifestFile.write(manifestContent)
}
2
Karim Varela

qu'en est-il? ajouter à build.gradle (module d'application)

def getBuildVersionCode() {
    def date = new Date()
    def formattedDate = date.format('yyyyMMdd')
    def formattedSeconds = date.format('HHmmssSSS')
    def formatInt = formattedDate as int;
    def SecondsInt = formattedSeconds as int;
    return (formatInt + SecondsInt) as int
}

   defaultConfig {
    applicationId "com.app"
    minSdkVersion 17
    targetSdkVersion 22
    versionCode getBuildVersionCode()
    versionName "1.0"
}
1
Karoly

Alors, alors que je cherchais une bonne partie de la solution, ils étaient gentils mais pas assez. J'ai donc écrit ceci, un incrément par déploiement multiple:

Cela incrémentera la construction lors de la compilation des versions de débogage et incrémentera le code de point et de version lors du déploiement.

import Java.util.regex.Pattern

def incrementVersionName(int length, int index) {
    def gradleFile = file("build.gradle")
    def versionNamePattern = Pattern.compile("versionName\\s*\"(.*?)\"")
    def gradleText = gradleFile.getText()
    def matcher = versionNamePattern.matcher(gradleText)
    matcher.find()

    def originalVersion = matcher.group(1)
    def originalVersionArray = originalVersion.split("\\.")
    def versionKeys = [0, 0, 0, 0]
    for (int i = 0; i < originalVersionArray.length; i++) {
        versionKeys[i] = Integer.parseInt(originalVersionArray[i])
    }
    def finalVersion = ""
    versionKeys[index]++;
    for (int i = 0; i < length; i++) {
        finalVersion += "" + versionKeys[i]
        if (i < length - 1)
            finalVersion += "."
    }

    System.out.println("Incrementing Version Name: " + originalVersion + " ==> " + finalVersion)

    def newGradleContent = gradleText.replaceAll("versionName\\s*\"(.*?)\"", "versionName \"" + finalVersion + "\"")
    gradleFile.write(newGradleContent)
}

def incrementVersionCode() {
    def gradleFile = file("build.gradle")
    def versionCodePattern = Pattern.compile("versionCode\\s*(\\d+)")
    def gradleText = gradleFile.getText()
    def matcher = versionCodePattern.matcher(gradleText)
    matcher.find()

    def originalVersionCode = Integer.parseInt(matcher.group(1) + "")
    def finalVersionCode = originalVersionCode + 1;
    System.out.println("Incrementing Version Code: " + originalVersionCode + " ==> " + finalVersionCode)

    def newGradleContent = gradleText.replaceAll("versionCode\\s*(\\d+)", "versionCode " + finalVersionCode)
    gradleFile.write(newGradleContent)
}

task('incrementVersionNameBuild') << {
    incrementVersionName(4, 3)
}

task('incrementVersionNamePoint') << {
    incrementVersionName(3, 2)
}

task('incrementVersionCode') << {
    incrementVersionCode()
}


def incrementedBuild = false
def incrementedRelease = false

tasks.whenTaskAdded { task ->
    System.out.println("incrementedRelease: " + incrementedRelease)
    System.out.println("incrementedBuild: " + incrementedBuild)
    System.out.println("task.name: " + task.name)

    if (!incrementedBuild && task.name.matches('generate.*?DebugBuildConfig')) {
        task.dependsOn 'incrementVersionNameBuild'
        incrementedBuild = true
        return
    }

    if (!incrementedRelease && task.name.matches('generate.*?ReleaseBuildConfig')) {
        task.dependsOn 'incrementVersionCode'
        task.dependsOn 'incrementVersionNamePoint'
        incrementedRelease = true
        return
    }
}
0
TacB0sS