versioncode una como cambiar android build android-manifest gradle auto-increment

una - Cómo autoincrementar versionCode en Android Gradle



android:versioncode (13)

Estoy experimentando con el nuevo sistema de compilación de Android basado en Gradle y estoy pensando, ¿cuál es la mejor manera de autoincrementar versionCode con él. Estoy pensando en dos opciones

  1. crea el archivo versionCode, lee el número, increméntalo y escríbelo de nuevo en el archivo
  2. analizar AndroidManifest.xml, leer el código de versión, aumentarlo y volver a escribirlo en el archivo AndroidManifest.xml

¿Hay alguna solución más simple o adecuada?

¿Alguien ha usado una de las opciones de mentiod y podría compartirla conmigo?


Incrementar la tarea de VersionCode (Entero):

Esto funciona incrementando el código de versión en 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) }

Incrementar VersionName Task (String):

Advertencia: debe contener 1 período para Regex

Esto funciona incrementando el nombre de la versión por 0.01 , por ejemplo: puede modificar y cambiar fácilmente su incremento o agregar 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 de:

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


Así que mientras estudiaba la mayor parte de la solución, eran agradables pero no lo suficiente, así que escribí esto, un incremento por despliegue múltiple:

Esto incrementará la compilación al compilar versiones de depuración e incrementará el código de punto y versión cuando se implemente.

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


Estoy usando este código para actualizar tanto versionCode como versionName, usando un esquema "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'' } }


Estoy usando la marca de tiempo para el código de la versión:

def date = new Date() def formattedDate = date.format(''yyMMddHHmm'') def code = formattedDate.toInteger() defaultConfig { minSdkVersion 10 targetSdkVersion 21 versionCode code }


He decidido por la segunda opción: analizar AndroidManifest.xml . Aquí está el fragmento de trabajo.

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 se lanza para compilaciones de lanzamiento en este caso. Para aumentarlo para las compilaciones de depuración, cambie la ecuación task.whenTaskAdded en la task.whenTaskAdded llamada task.whenTaskAdded .


La versión de compilación avanzada de Gradle es un complemento para Android que hace que se generen versionCode y versionName automáticamente. hay mucha personalización. aquí puedes encontrar más información al respecto https://github.com/moallemi/gradle-advanced-build-version


Mi enfoque es leer el archivo manifest de la carpeta de compilación y obtener buildVersion de allí, que eliminar una carpeta. Cuando la tarea crea un nuevo manifiesto, mi variable buildVersion incrementada ya está allí.

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


Para agregar a la publicación de @ sealskej, esta es la forma de actualizar tanto el código de la versión como el nombre de la versión (Aquí estoy suponiendo que su versión principal y secundaria son ambas 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) }


Para tener en cuenta los sabores de los productos y los tipos de compilación y usar la lógica de @sealskej para analizar el 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) } }


Si escribe su versionCode en el archivo gradle.build (la mayoría de los casos actualmente), aquí hay una solución. Un poco estúpido (actualización "self"), 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'' } }


Si mantiene el código de versión en el archivo build.gradle use el siguiente fragmento:

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


no parece ser la configuración exacta que está utilizando, pero en mi caso las compilaciones están siendo ejecutadas por jenkins y quería usar su $ BUILD_NUMBER como código de versión de la aplicación. Lo siguiente hizo el truco para mí allí.

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


que tal esto? agregar a build.gradle (módulo de aplicación)

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