Autoincrement VersionCode с дополнительными свойствами gradle

Я создаю приложение Android с gradleиентом. До сих пор я использовал файл манифеста для увеличения версииCode, но я хотел бы прочитать версию Code из внешнего файла и в зависимости от того, является ли это аромат релиза или отладочный вкус, увеличьте версию Code. Я попробовал дополнительные свойства, но вы не можете их сохранить, а это значит, что в следующий раз, когда я его построю, я получаю тот же код версии. Любая помощь будет очень высоко ценится!

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

Я хотел бы прочитать версию Code из внешнего файла

Я уверен, что существует множество возможных решений; вот одно:

 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 } 

Этот код ожидает существующий файл version.properties , который вы создадите вручную до того, как первая версия будет иметь VERSION_CODE=8 .

Этот код просто ударяет код версии для каждой сборки – вам нужно будет расширить технику для обработки вашего кода версии для каждого аромата.

Вы можете увидеть пример проекта Версии , демонстрирующий этот код.

Здесь идет модернизация моего предыдущего ответа, который можно увидеть ниже. Это работает с Gradle 4.4 и Android Studio 3.1.1 .

Что делает этот скрипт:

  • Создает файл version.properties, если он не существует (см. Ниже ответ Пауля Кантрелла, откуда я получил эту идею, если вам нравится этот ответ)
  • Для каждой сборки, отладочной версии или в любое время, когда вы нажимаете кнопку запуска в Android Studio, число VERSION_BUILD увеличивается.
  • Каждый раз, когда вы собираете релиз, ваш Android- код версии для магазина воспроизведения увеличивается, а число патчей увеличивается.
  • Бонус: после завершения сборки копирует ваш apk в projectDir/apk чтобы сделать его более доступным.

Этот скрипт создаст номер версии, который выглядит как v1.3.4 (123) и построит файл apk, такой как AppName-v1.3.4.apk .

 Major version ⌄ ⌄ Build version v1.3.4 (123) Minor version ⌃|⌃ Patch version 

Основная версия: должна быть изменена вручную для больших изменений.

Незначительная версия: должна быть изменена вручную для слегка меньших изменений.

Версия патча: Увеличивается при запуске gradle assembleRelease

Версия сборки: увеличивает каждую сборку

Номер версии: такая же, как версия Patch , это для кода версии, который Play Store должен увеличить для каждой новой загрузки apk.

Просто измените содержание в комментариях, помеченных как 1 – 3 ниже, и сценарий должен сделать все остальное. 🙂

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

================================================== ==

НАЧАЛЬНЫЙ ОТВЕТ:

Я хочу, чтобы versionName также увеличивалось автоматически. Так что это просто дополнение к ответу CommonsWare, который отлично работал для меня. Это то, что работает для меня

 defaultConfig { versionCode code versionName "1.1." + code minSdkVersion 14 targetSdkVersion 18 } 

РЕДАКТИРОВАТЬ:

Поскольку я немного ленив, я хочу, чтобы мое управление версиями работало максимально автоматически. Я хочу иметь версию сборки, которая увеличивается с каждой сборкой, а номер версии и имя версии увеличивается только тогда, когда я делаю сборку релиза.

Это то, что я использовал в течение прошлого года, основы из ответа CommonsWare и моего предыдущего ответа, а также еще несколько. Это приводит к следующей версии:

Название версии: 1.0.5 (123) -> Major.Minor.Patch (Build), Major и Minor изменяются вручную.

В 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 и versionCode увеличивается, если вы собираете свой проект через терминал с помощью «собрать» , «assembleRelease» или «aR», который создает новую папку в корне вашего проекта под названием apk / RELEASE, поэтому вам не нужно просматривать сборки / выходы / more / more / more, чтобы найти ваш apk.

Свойства вашей версии должны выглядеть следующим образом:

 VERSION_NUMBER=1 VERSION_BUILD=645 VERSION_PATCH=1 

Очевидно, начните с 0. 🙂

Немного затянутая версия замечательного ответа CommonsWare создает файл версии, если он не существует:

 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 } 

Я просмотрел несколько вариантов для этого и в конечном итоге решил, что просто использовать текущее время для версииCode вместо того, чтобы пытаться автоматически увеличивать версию Code и проверять ее на мою систему контроля версий.

Добавьте в свой 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 } } 

Однако, если вы планируете загружать сборки за год 2696, вы можете использовать другое решение.

Другим способом получения versionCode версии автоматически является параметр versionCode для количества коммитов в проверенной ветке git . Он выполняет следующие задачи:

  1. versionCode генерируется автоматически и последовательно на любом компьютере (включая сервер Continuous Integration и / или Continuous Deployment ).
  2. Приложение с этой versionCode отправляется в GooglePlay.
  3. Не полагается на файлы вне репо.
  4. Не подталкивает ничего к репо
  5. Может быть вручную переопределено, если необходимо

Использование библиотеки gradle-git для достижения вышеуказанных целей. Добавьте код ниже в файл build.gradle каталоге /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 /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  | wc -l def numOfCommits = ext.repo.log().size() return numOfCommits } 

ПРИМЕЧАНИЕ. Чтобы этот метод работал, лучше всего использовать его только в Google Play Store из той же ветви (например, master ).

Недавно я работал над плагином для Android, который автоматически генерирует VersionCode и versionName . есть много настроек. здесь вы можете найти дополнительную информацию об этом https://github.com/moallemi/gradle-advanced-build-version

Другой вариант, для увеличения значения versionCode и versionName , используется timestamp.

 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 } 

Начиная с 1 января 2022 г. formattedDate = date.format (‘yyMMddHHmm’) превышает емкость целых чисел

Чтобы увеличить код версии только в версии выпуска, выполните следующие действия:

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

ожидает существующий файл c://YourProject/app/version.properties , который вы создали бы вручную до того, как первая c://YourProject/app/version.properties будет иметь VERSION_CODE=8

Файл version.properties :

VERSION_CODE=8

Создать файл version.properties

 MAJOR=1 MINOR=3 PATCH=6 VERSION_CODE=1 

Изменить 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 } 

}

Выход: 1.1.3.6

Определить имя версии в AndroidManifest.xml

 android:versionName="5.1.5" 

Внутри android{...} блок в build.gradle уровня приложения:

 defaultConfig { applicationId "com.example.autoincrement" minSdkVersion 18 targetSdkVersion 23 multiDexEnabled true def version = getIncrementationVersionName() versionName version } 

Вне android{...} block в build.gradle уровня приложения:

 def getIncrementedVersionName() { List 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 } 

После создания пения APK:

 android:versionName="5.1.6" 

Примечание. Если ваша версияName отличается от моей, вам нужно изменить регулярное выражение и извлечь часть логики .

Кредиты для CommonsWare (принятый ответ) Пол Кантрелл (создайте файл, если он не существует) ahmad aghazadeh (название и код версии)

Поэтому я объединил все свои идеи и придумал это. Это решение для перетаскивания точно так, как просил первый пост.

Он автоматически обновит versionCode и versionName в соответствии с статусом релиза. Конечно, вы можете перемещать переменные, чтобы удовлетворить ваши потребности.

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

Используя Gradle Task Graph, мы можем проверить / изменить тип сборки.

Основная идея состоит в том, чтобы увеличить значение версии Code для каждой сборки. На каждой строят счетчик, хранящийся в файле version.properties . Он будет обновляться при каждой новой сборке APK и заменять строку versionCode в файле build.gradle с этим увеличенным значением счетчика.

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

Поместите вышеуказанный скрипт в свой файл build.gradle основного модуля.

Ссылка на сайт: http://devdeeds.com/auto-increment-build-number-using-gradle-in-android/

С уважением!

  • Конфигурация прокси-сервера Gradle
  • Студия Android, gradle и NDK
  • «зависимости» не могут применяться к «(groovy.lang.Closure)»
  • Как включить зависимость библиотечного модуля в проекте Android Studio?
  • Android Studio: Gradle: ошибка: не удается найти символьную переменную
  • Предупреждение о недоставке: variant.getOutputFile () и variant.setOutputFile () устарели
  • Добавить ViewPagerIndicator в Android Studio
  • Как обеспечить различные значки приложений для Android для разных типов шаблонов gradle?
  • Метод Gradle DSL не найден: 'runProguard'
  • Ошибка: Ошибка выполнения для задачи «: app: dexDebug» в моем проекте, в то время как я добавил новую зависимость
  • Как установить различное приложение для каждой комбинации вкуса с использованием flavorDimensions?
  • Давайте будем гением компьютера.