Estoy experimentando con un nuevo sistema de compilación de Android basado en Gradle y estoy pensando, ¿cuál es la mejor manera de aumentar automáticamente versionCode con él? Estoy pensando en dos opciones
- crear el archivo versionCode, leer el número de él, aumentarlo y escribirlo de nuevo en el archivo
- analizar AndroidManifest.xml, leer versionCode de él, aumentarlo y escribirlo de nuevo en AndroidManifest.xml
¿Existe alguna solución más sencilla o adecuada?
¿Alguien ha usado una de las opciones de mentiod y podría compartirla conmigo?
android
build
android-manifest
gradle
auto-increment
sealskej
fuente
fuente
version.properties
archivo stackoverflow.com/a/21405744Respuestas:
Me 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 versiones de lanzamiento en este caso. Para aumentarlo para las compilaciones de depuración, cambie la ecuación task.name en latask.whenTaskAdded
devolución de llamada.fuente
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' } }
fuente
Error:(48) Execution failed for task ':app:incrementVersionName'. > No match found
Alguna idea?android:versionName="0.0.0.1"
en el manifiesto, de lo contrario, no se esperará un número de coincidenciasFull recompilation is required because 'BuildConfig.java' was changed.
no parece ser la configuración exacta que estás usando, pero en mi caso las compilaciones están siendo ejecutadas por jenkins y quería usar su $ BUILD_NUMBER como el 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 ... }
fuente
System.getenv()
en el gradle.Estoy usando la marca de tiempo para el código de versión:
def date = new Date() def formattedDate = date.format('yyMMddHHmm') def code = formattedDate.toInteger() defaultConfig { minSdkVersion 10 targetSdkVersion 21 versionCode code }
fuente
Si tiene el código de la 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) }
fuente
versionCode 18
. Incluso si ejecuté su expresión regular en un tester ("versionCode \d+"
), no coincidirá.versionCode
y el dígito, ya que se alineará con el texto enversionName
.Gradle Advanced Build Version es un complemento para Android que permite generar versionCode y versionName automáticamente. hay mucha personalización. aquí puede encontrar más información al respecto https://github.com/moallemi/gradle-advanced-build-version
fuente
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) } }
fuente
Incrementar la tarea de código de versión (entero):
Esto funciona incrementando el código de versión
1
, por ejemplo:android:versionCode="1"
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 la tarea de VersionName (cadena):
Advertencia: debe contener un
1
período para RegexEsto funciona incrementando el Nombre de la versión
0.01
, por ejemplo: Puede modificar y cambiar fácilmente su incremento o agregar más dígitos.android:versionName="1.0"
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" >
fuente
Si escribe su archivo
versionCode
ingradle.build
(la mayoría de los casos actualmente), aquí hay una solución. Un poco estúpido (actualizar "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' } }
fuente
Para agregar a la publicación de @ sealskej, así es como puede actualizar tanto el código de su versión como el nombre de la versión (aquí supongo 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) }
fuente
que hay de esto agregar a build.gradle (módulo de la 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" }
fuente
(20160129 + 000000000) < (20160128 + 125959999)
Entonces, mientras buscaba la mayor parte de la solución, eran agradables pero no lo suficiente, así que escribí esto, un incremento por implementación múltiple:
Esto incrementará la compilación al compilar versiones de depuración e incrementará el punto y el código de versión al 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 } }
fuente
Mi enfoque es leer el archivo de manifiesto de la carpeta de compilación y sacar buildVersion de allí, luego borrar 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 ]} }
fuente