Cómo autoincrement versionCode en Android Gradle

Estoy experimentando con el nuevo Android de construir un sistema basado en Gradle y estoy pensando en, ¿cuál es la mejor manera de autoincrease versionCode con ella. Estoy pensando en dos opciones

  1. crear versionCode archivo, leer el número de ella, aumentar y escribir en el archivo
  2. analizar AndroidManifest.xml, leer versionCode de ella, aumentar y escribir en el AndroidManifest.xml

Es más simple o la solución adecuada?

Alguien ha utilizado uno de mentiod opciones y poder compartirla conmigo?

InformationsquelleAutor sealskej | 2013-07-03

13 Kommentare

  1. 56

    He decidido por la segunda opción – para analizar AndroidManifest.xml. Aquí está trabajando fragmento.

    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 es liberado para las versiones de lanzamiento en este caso. Para aumentar versiones de depuración del cambio de tarea.nombre de ecuación en task.whenTaskAdded de devolución de llamada.

    • una pregunta, ¿cómo integrar esas código a la Base del sistema de compilación?
    • También, un poco más limpio respuesta aquí no modificar XML en el lugar, pero mantiene el número de versión en un archivo props: stackoverflow.com/questions/21405457/…
    • Solo cambiar el archivo(«AndroidManifest.xml») a un archivo(«src/main/AndroidManifest.xml») si usted está utilizando la nueva estructura del proyecto.
    • Lo que si no estoy de establecer versionCode en mi AndroidManifest.xml?
    • Si ustedes todavía no tengo una solución, véase mi respuesta: stackoverflow.com/a/39619297/1150251
    • Yo no puedo ir, ¿cómo se trabaja?
    • se debe añadir la siguiente línea a su app/build.gradle de archivo: import java.util.regex.Pattern Insertar esta línea después de apply plugin ...sección

  2. 39

    Estoy usando este código para actualizar versionCode y versionName, el uso de una «importante.menor de edad.el parche.construir» el esquema.

    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'
        }
    }
    • +1 por la cantidad de control que usted consigue
    • Se le olvidó a la importación de Patrón en la parte superior: import java.util.regex.Patrón
    • Solucionado, gracias!
    • ¿Cómo puedo obtener el gradle archivo para actualizar también?
    • Sé que este es un poco viejo, pero bueno que no hacen daño a preguntar, pero he intentado utilizar el fragmento anterior, estoy recibiendo este error Error:(48) Execution failed for task ':app:incrementVersionName'. > No match found alguna idea?
    • asegúrese de que establece android:versionName="0.0.0.1" en el manifiesto de los demás, no se espera que el número de partidos
    • Su trabajo a la perfección, pero en BuildConfig.java versionName está vacía, public static final String VERSION_NAME = «»;
    • Cuidado con ese «Instante de Ejecutar» en Android Studio sería más lento, porque Full recompilation is required because 'BuildConfig.java' was changed.
    • ¿Qué pasa si yo no uso el AndroidManifest archivo?
    • Cómo importar estos valores en la construcción.gradle?
    • no importa, he encontrado la solución 🙂

  3. 36

    no parece ser la configuración exacta que usted está utilizando, pero en mi caso a que las compilaciones son jenkins y quería usar su $BUILD_NUMBER como la aplicación del versionCode. los siguientes hizo el truco para mí no.

    defaultConfig {
        ...
        versionCode System.getenv("BUILD_NUMBER") as Integer ?: 9999
        ...
    }
    • ¿Qué es el Sistema.genenv?
    • Esto realmente me ayudó mucho cuando el uso de Jenkins. Usted puede utilizar este este plugin para crear environmt variable con el número de compilación y leerlo con System.getenv() en el gradle.
  4. 15

    Estoy utilizando marca de tiempo de la versión de código:

    def date = new Date()
    def formattedDate = date.format('yyMMddHHmm')
    def code = formattedDate.toInteger()
    
    defaultConfig {
        minSdkVersion 10
        targetSdkVersion 21
        versionCode code
    }
    • esto es simple y el genio. pulgares para arriba
  5. 7

    Si usted está sosteniendo el código de la versión en la construcción.gradle archivo utilice el siguiente fragmento de código:

    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)
    }
    • Ese patrón no es coincidente con la versionCode.
    • Puede publicar su construcción.gradle?
    • Mi generación.gradle es una parte normal de la acumulación de archivo. VersionCode línea parece versionCode 18 . Aun cuando me encontré con su expresión regular en un probador ("versionCode \d+") no coinciden.
    • El error fue que uno de los más espacio en blanco. Android Studio el uso de dos espacios en blanco en versionCode y el dígito, ya que se alinee con el texto en versionName.
    • Ahora debería funcionar, lo siento por eso.
  6. 4

    Tomar ambos productos y sabores de construir tipos en los que se cuenta y el uso de @sealskej de la lógica para el análisis de manifiesto:

    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)
        }
    }
    • Dónde tenemos que escribir esto… me refiero a en que clase de archivo/este código necesita ser añadido
    • esto es parte de la construcción.gradle ya que esto es parte del proceso de compilación
  7. 3

    Incremento VersionCode Tarea(Entero):

    Esto funciona mediante el incremento de la Versión de Código por 1, por ejemplo:

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

    Incremento VersionName Tarea(String):

    Advertencia: Debe contener 1 período de Regex

    Esto funciona mediante el incremento de la Versión Nombre por 0.01, por ejemplo:
    Usted puede modificar fácilmente y cambiar su incremento o añadir más dígitos.

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

    Antes:

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

    Despué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" >
  8. 2

    Para agregar a @sealskej del post, esta es la forma en que usted puede actualizar su versión de código y nombre de la versión (Aquí estoy asumiendo que su versión principal y secundaria son ambos 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)
    }
  9. 2

    Si usted escribe su versionCode en gradle.build archivo(la mayoría de los casos en la actualidad), aquí es una solución. Un poco estúpido(actualización de «auto»), pero funciona!

    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'
        }
    }
  10. 1

    lo que acerca de esto ?
    añadir a construir.gradle (módulo app)

    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"
    }
    • Gran reflexión, pero (20160129 + 000000000) < (20160128 + 125959999)
  11. 0

    Así como que yo estaba buscando en la mayor parte de la solución, ellos eran buenos, pero no lo suficiente para que yo escribí esto, un incremento por multi-implementar:

    Esto incrementará la generación, cuando la compilación de las versiones de depuración, y el incremento de un punto y código de la versión de la hora de implementar.

    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
        }
    }
  12. -1

    Mi enfoque es leer el archivo de manifiesto de la carpeta de compilación y obtener la versión de compilación de ahí, que puedo borrar una carpeta. La tarea cuando se crea un nuevo manifiesto, mi incrementa versión de compilación variable que ya existe.

    def versionPattern = "Implementation-Version=(\\d+.\\d+.\\d+.\\d+\\w+)"
    
    task generateVersion (dependsOn : 'start') {
        //read build version from previous manifest
        def file = file("build/libs/MANIFEST.MF")
        if (file.exists()) {
            def pattern = Pattern.compile(versionPattern)
            def text = file.getText()
            def matcher = pattern.matcher(text)
            matcher.find()
            buildNumber = Integer.parseInt(matcher.group(1))
            //increment build version
            version = "${majorVer}.${minorVer}.${patchVer}.${++buildNumber}${classifier}_${access}"
        } 
        else 
            version = "${majorVer}.${minorVer}.${patchVer}.1${classifier}_${access}"
    }
    
    task specifyOutputDir (dependsOn : 'generateVersion', type : JavaCompile) {
        //create a folder for new build
        destinationDir = file("build/${version}/")
    }
    
    task clean (dependsOn : 'generateVersion', type : Delete) {
        doLast {
            delete "build/${version}"
            println 'Build directory is deleted'
        }
    }
    
    task configureJar (dependsOn : 'generateVersion', type : Jar) {
        baseName = applicationName
        version = project.version
        archiveName = "${applicationName}_ver${version}.${extension}"
        manifest {[
                "Main-Class" : mainClassName,
                "Implementation-Title" : name,
                "Implementation-Version" : version,
                "Access" : access,
                "Developer" : developer
        ]}
    }

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea