android - Autoincrement VersionCode con propiedades adicionales de gradle
android-gradle build.gradle (12)
Me gustaría leer la versionCode de un archivo externo
Estoy seguro de que hay muchas soluciones posibles. Aqui hay uno:
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
}
Este código espera un archivo version.properties
existente, que crearía a mano antes de la primera compilación para tener VERSION_CODE=8
.
Este código simplemente topa con el código de la versión en cada compilación. Tendría que ampliar la técnica para manejar su código de versión por sabor.
Puede ver todo el proyecto de muestra que demuestra este código.
Estoy construyendo una aplicación para Android con Gradle. Hasta ahora utilicé el archivo Manifest para aumentar el código de versión, pero me gustaría leer el código de versión desde un archivo externo y dependiendo de si es el sabor de la versión o el sabor de depuración aumentar el código de versión. Probé las propiedades adicionales, pero no puede guardarlas, lo que significa que la próxima vez que lo haga obtendré el mismo código de versión. ¡Cualquier ayuda sería muy apreciada!
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''
}
Aquí viene una modernización de mi respuesta anterior que se puede ver a continuación. Este se ejecuta con Gradle 4.4 y Android Studio 3.1.1 .
Lo que hace este script:
- Crea un archivo version.properties si no existe (vote por encima la respuesta de Paul Cantrell a continuación, que es de donde saqué la idea si le gusta esta respuesta)
- Para cada compilación, versión de depuración o cada vez que presione el botón Ejecutar en Android Studio, el número de VERSION_BUILD aumenta.
- Cada vez que ensamblas un lanzamiento, aumenta el código de tu versión de Android para Play Store y aumenta tu número de parche .
- Bonificación: una vez que se
projectDir/apk
su apk enprojectDir/apk
para hacerlo más accesible.
Este script creará un número de versión que se parece a v1.3.4 (123)
y v1.3.4 (123)
un archivo apk como AppName-v1.3.4.apk .
Major version ⌄ ⌄ Build version
v1.3.4 (123)
Minor version ⌃|⌃ Patch version
Versión principal: tiene que cambiarse manualmente para cambios más grandes.
Versión menor: tiene que cambiarse manualmente para cambios ligeramente menores.
Versión de parche: aumenta al ejecutar gradle assembleRelease
Versión de compilación: aumenta cada compilación
Número de versión: al igual que la versión de parche , esto es para el código de versión que Play Store necesita haber aumentado para cada nueva carga de apk.
Simplemente cambie el contenido en los comentarios etiquetados 1 - 3 a continuación y el script debería hacer el resto. :)
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 {
...
}
}
=============================================== ==
RESPUESTA INICIAL:
Quiero que versionName aumente automáticamente también. Así que esto es solo una adición a la respuesta de CommonsWare que funcionó perfectamente para mí. Esto es lo que funciona para mí
defaultConfig {
versionCode code
versionName "1.1." + code
minSdkVersion 14
targetSdkVersion 18
}
EDITAR:
Como soy un poco vago, quiero que mi versión funcione lo más automáticamente posible. Lo que quiero es tener una versión de compilación que aumente con cada compilación, mientras que el número de versión y el nombre de la versión solo aumentan cuando realizo una compilación de lanzamiento.
Esto es lo que he estado usando durante el año pasado, los conceptos básicos provienen de la respuesta de CommonsWare y mi respuesta anterior, más algunos más. Esto da como resultado el siguiente control de versiones:
Nombre de la versión: 1.0.5 (123) -> Major.Minor.Patch (Build), Major y Minor se cambian manualmente.
En 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 y versionCode aumentan si ensambla su proyecto a través del terminal con ''assemble'' , ''assembleRelease'' o ''aR'', que crea una nueva carpeta en la raíz del proyecto llamada apk / RELEASE para que no tenga que mirar a través de build / outputs / más / más / más para encontrar tu apk.
Las propiedades de su versión deberían verse así:
VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1
Obviamente comienza con 0. :)
Créditos a CommonsWare (Respuesta aceptada) Paul Cantrell (Crear archivo si no existe) ahmad aghazadeh (Nombre y código de la versión)
Así que aplasté todas sus ideas y se me ocurrió esto. Esta es la solución de arrastrar y soltar exactamente lo que pidió la primera publicación.
Se actualizará automáticamente el versionCode y el versionName según el estado de la versión. Por supuesto, puede mover las variables para adaptarlas a sus necesidades.
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
}
Crear archivo version.properties
MAJOR=1
MINOR=3
PATCH=6
VERSION_CODE=1
Cambiar 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
}
}
Salida: 1.1.3.6
Definir versionName en AndroidManifest.xml
android:versionName="5.1.5"
Dentro de android{...}
bloque en build.gradle
de nivel de aplicación:
defaultConfig {
applicationId "com.example.autoincrement"
minSdkVersion 18
targetSdkVersion 23
multiDexEnabled true
def version = getIncrementationVersionName()
versionName version
}
Bloque externo de android{...}
en build.gradle
de nivel de aplicación:
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
}
Después de crear el APK chamuscado:
android:versionName="5.1.6"
Nota: Si su versionName es diferente de my, necesita cambiar la expresión regular y extraer la lógica de partes .
Miré algunas opciones para hacer esto, y finalmente decidí que era más simple usar la hora actual para el código de versión en lugar de tratar de incrementar automáticamente el código de versión y verificarlo en mi sistema de control de revisiones.
Agregue lo siguiente a su 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
}
}
Sin embargo, si espera subir construcciones más allá del año 2696, es posible que desee utilizar una solución diferente.
Otra forma de obtener un versionCode
automáticamente es establecer el versionCode
de versionCode
en el número de confirmaciones en la rama de git
desprotegida. Cumple los siguientes objetivos:
-
versionCode
se genera de forma automática y coherente en cualquier máquina (incluido un servidor deContinuous Integration
y / oContinuous Deployment
). - La aplicación con este
versionCode
se puede enviar a GooglePlay. - No confía en ningún archivo fuera del repositorio.
- No empuja nada al repositorio
- Se puede anular manualmente, si es necesario
Usando la biblioteca gradle-git para lograr los objetivos anteriores. Agregue el siguiente código a su archivo build.gradle
, el directorio /app
:
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
}
NOTA: Para que este método funcione, lo mejor es implementarlo solo en Google Play Store desde la misma rama (por ejemplo, master
).
Otra opción, para incrementar el versionCode
y el versionName
, es utilizar una marca de tiempo.
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
}
A partir del 1 de enero de 2022 formattedDate = date.format (''yyMMddHHmm'') excede la capacidad de los enteros
Para incrementar versionCode solo en la versión de lanzamiento, hazlo:
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
}
espera un archivo c://YourProject/app/version.properties
existente, que crearía a mano antes de la primera compilación para tener VERSION_CODE=8
Archivo version.properties
:
VERSION_CODE=8
Recientemente estuve trabajando en un plugin de gradle 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
Una versión ligeramente ajustada de la excelente respuesta de CommonsWare crea el archivo de versión si no existe:
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
}
Usando Gradle Task Graph podemos verificar / cambiar el tipo de compilación.
La idea básica es incrementar el versionCode en cada compilación. En Cada compilación, un contador almacenado en el archivo version.properties . Se mantendrá actualizado en cada nueva compilación de APK y reemplazará la cadena versionCode en el archivo build.gradle con este valor de contador incrementado.
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''
}
Coloque la secuencia de comandos anterior dentro de su archivo build.gradle del módulo principal.
Sitio web de referencia: http://devdeeds.com/auto-increment-build-number-using-gradle-in-android/
¡Gracias y Saludos!