Автокредитування VersionCode з додатковими властивостями gradle


121

Я будую додаток для Android з gradle. До цього часу я використовував файл Manifest для збільшення versionCode, але я хотів би прочитати versionCode із зовнішнього файлу і залежно від того, чи є аромат випуску або аромат налагодження збільшить versionCode. Я спробував додаткові властивості, але ви не можете їх зберегти, це означає, що наступного разу, коли я будую його, я отримую ту ж версію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'
}

Дивіться моя відповідь тут: stackoverflow.com/a/33637600/348189
TacB0sS

Ще один варіант (підхід до встановлення та забуття): medium.com/@passsy/…
Simon B.

Один лайнер з вашим вибором Gradle плагінів: stackoverflow.com/a/61718437/4548500
SUPERCILEX

Відповіді:


207

Я хотів би прочитати versionCode із зовнішнього файлу

Я впевнений, що існує будь-яка кількість можливих рішень; ось одне:

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.

Цей код просто стикається з кодом версії для кожної збірки - вам потрібно буде розширити техніку для обробки коду версії за ароматом.

Ви можете побачити зразок проекту Версія, який демонструє цей код.


4
Як увімкнути збільшення цієї версії лише під час створення версій версій?
Пьотр

@Piotr: Якщо ви маєте на увазі "збільшити лише кількість у збірці випусків", це повинно бути можливим, хоча я не знаю деталей. Особисто, оскільки є близько 2 мільярдів кодів версій, я припускаю, що мене не закінчиться. :-)
CommonsWare

3
@Piotr ви створили б завдання, яке окремо збільшує код версії, а потім зробить щось подібне assembleRelease.finalizedBy incrementVersionабо щось подібне. Я опублікую свій код, як тільки його приберу.
Chris.Jenkins

За допомогою спеціального завдання ви можете просто зробити щось на кшталт ./gradlew incrementVersionCode build. Завдання, покликані послідовно таким чином, припиняться, як тільки будь-яке із завдань не виконане.
Дорі

3
Оскільки @ chris.jenkins все ще виправляє свій код: p Ось наведене вище у формі завдання та методу gist.github.com/doridori/544c24509be236c11fd5, яку можна використовувати всередині DSL для android зversionCode getIncrementingVersionCode()
Дорі

83

Ось іде модернізація моєї попередньої відповіді, яку можна побачити нижче. Цей працює з Gradle 4.4 та Android Studio 3.1.1 .

Що робить цей сценарій:

  • Створює файл version.properties, якщо такого немає (до голосування відповіді Пола Кантрелла нижче, саме звідки я отримав ідею, якщо вам подобається ця відповідь)
  • З кожним складанням, випуском налагодження або будь-яким натисканням кнопки запуску в Android Studio число VERSION_BUILD збільшується.
  • Кожен раз , коли ви збираєте Реліз свого Android VersionCode для магазину збільшуються гри і вашого накладне число збільшується.
  • Бонус: Після завершення збірки скопіюйте свій 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

Основна версія: Для більших змін потрібно змінити її вручну.

Незначна версія: для невеликих менш великих змін потрібно змінити вручну.

Версія Patch: збільшується під час запуску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 {
        ...
    }
}

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

ПОЧАТОК ВІДПОВІДЬ:

Я хочу, щоб і версіяName автоматично збільшувалася. Тож це лише доповнення до відповіді CommonsWare, яка прекрасно працювала для мене. Це те, що працює для мене

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

Редагувати:

Оскільки я трохи лінивий, я хочу, щоб моя версія працювала максимально автоматично. Мені хочеться, щоб версія версії збільшилася з кожною збіркою, тоді як номер версії та назва версії збільшуються лише тоді, коли я створюю версію версії.

Це те, що я використовую останній рік, основи - це відповідь CommonsWare та моя попередня відповідь, а також ще кілька. Це призводить до наступної версії:

Назва версії: 1.0.5 (123) -> Major.Minor.Patch (Build), Major and 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 збільшується, якщо ви збираєте проект через термінал за допомогою "збирати" , "збиратиRelease" або "aR", що створює нову папку в корені проекту під назвою apk / RELEASE, так що вам не доведеться переглядати збірки / виходи / more / more / more, щоб знайти свій apk.

Властивості версії повинні мати такий вигляд:

VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1

Очевидно, почніть з 0. :)


2
Другий 'variant.outputs.each {output ->' можна видалити з відповідним '}'.
повторнокодер

Це призводить до того, що всі мої збірки знаходяться лише в
натурному

@Chisko Я сумніваюся, що цей фрагмент коду gradle є причиною. Задайте нове запитання і поділіться кодом Gradle, і ми можемо спробувати з'ясувати, що не так. :)
just_user

1
Зараз я можу підтвердити, що це не була першопричиною. Мої вибачення.
Чіско

1
@AlexanderGavriliuk - код версії, який використовує ігровий магазин, який постійно збільшується для кожного завантаження. Номер виправлення, ймовірно, буде скинутий, якщо ви збільшите основну або другорядну версію. Номер версії ніколи не повинен бути скинутий, якщо ви завантажите додаток у ігровий магазин з тим же найменуванням пакета.
just_user

40

Трохи затягнута версія відмінної відповіді 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
}

де частина про створення файлу версії, якщо він не існує?
портфоліобудівник

4
if(versionPropsFile.exists())гарантує, що він не вибухне, якщо файлу немає. versionProps.store(versionPropsFile.newWriter(), null) перезаписує файл незалежно від того, чи він уже існує.
Пол Кантрелл

Довелося перевірити, що ?:означає в Groovy. Оператор Елвіса - це скорочення потрійного оператора.
Даніель

30

Я переглянув кілька варіантів для цього, і, врешті-решт, вирішив, що простіше просто використати поточний час для versionCode, а не намагатися автоматично збільшити versionCode і перевірити його в моїй системі контролю версій.

Додайте до свого 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 року, можливо, ви хочете скористатися іншим рішенням.


2
Якщо ви читаєте це зараз, і починаючи з нового додатка, можете 1510351294
підсунути

я не отримую це !! Ви не використовуєте аналітику чи крашлітики чи будь-яку іншу службу, яка надає дані з кодами версій та назвами? а ти з цим легко граєш?
Амір Зіараті

Якщо у вас є розумні назви версій, я думаю, це добре. Crashalytics також надає назву версії.
netcyrax

@emmby, звідки ви берете номер "1451606400"? або "1510351294" від #Entreco я намагався обчислити даремно!
Джозеф Вамбура

18

Іншим способом 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 <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
}

ПРИМІТКА. Щоб цей метод працював, найкраще розгорнути лише в Google Play Store з тієї ж гілки (наприклад master).


хоча по суті елегантне рішення, я можу уявити, що це різко уповільнить час збирання, залежно від того, що саме відбувається в 2 git рядках. Будь-який досвід з цього приводу?
СподіваюсьДопомога

1
Я не помічаю жодного покращення продуктивності, якщо цей крок відключений. Використовували метод локально та на наших машинах для побудови вже більше року, а продуктивність взагалі не була проблемою. Якщо ви помітили якісь проблеми щодо ефективності, повідомте мене!
C0D3LIC1OU5

Хоча ваше рішення вишукане, воно може подарувати неприємні несподівані сюрпризи. Важливо, що версіяCodes завжди більша, ніж у попередньому випуску. Що робити, якщо у вас є одна гілка з 50 комітами, а потім ви створюєте іншу гілку, яка є новішою, але має лише 40 комітів, можливо, через зменшення кількості комітетів з якоїсь об'єднаної функції. Я бачу безліч причин, коли ваша історія фіксованості не завжди була б лінійним потоком поступових комісій.
JHH

@JHH Ці результати не є несподіваними. Як я вже згадував у примітці, цей метод найкраще працює при розгортанні з тієї ж гілки.
C0D3LIC1OU5


10

Ще одним варіантом збільшення versionCodeта versionName, є використання часової позначки.

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') перевищує потужність цілих літрів


1
Людина хотіла номер збірки для автоматичного збільшення
peter_pilgrim

6
@peter_pilgrim Caro - це ОП.
Матвій

Я думаю, що це елегантне рішення, воно не покладається на файли, які можуть зникнути чи ні, або які постійно з’являться в git. Це також допомагає вам однозначно визначити кожну конструкцію принаймні протягом наступних десятків 22 років.
СподіваюсьДопомога

процитувати developer.android.com:"Warning: Найбільше значення Google Play дозволяє VersionCode це 2100000000. "Так, відсічення насправді 2021
тис

Виправте обмеження int: опустіть хвилини та використовуйте формат дати 'yyMMddHH', код версії міститиме принаймні години.
Покажчик Нуль

10

Щоб збільшити versionCode лише у версії випуску, зробіть це:

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
    }

очікує наявний c://YourProject/app/version.propertiesфайл, який ви створили б вручну перед першою збіркоюVERSION_CODE=8

Файл version.properties:

VERSION_CODE=8


Замість того, щоб поставити його всередині завдання і зробити генераторReleaseBuildConfig залежить від цього завдання.
Лагос

versionName "1.0." + getSvnRevision () викликає помилку. Де посилається на метод getSvnRevision ()? Ви впевнені, що це не повинно бути версіяName "1.0." + Код (назва версії збільшиться з кодом версії)?
portfoliobuilder

1
@portfoliobuilder, замініть getSvnRevision () на код
NickUnuchek

4

Створити файл 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


Дякую. І чому ви вставили versionCode у versionName? Навіть на другій позиції.
CoolMind

Але, наприклад, це виглядатиме як 1,71,3,76. Я думаю, що краще - 1,3,76, відокремивши його від коду версії.
CoolMind

Так . ви можете змінити "$ {_} великий .. $ {_ другорядний} $ {_ латки} $ {_ VersionCode} .." або видалити патч
Ahmad Агазаде

якщо (_major == 99) має бути if (_minor == 99) ??
Anirudh Баграм

2

Визначити versionName у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{...}блок build.gradleрівня програми:

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
}

Після створення створеного APK:

android:versionName="5.1.6"

Примітка: Якщо ваша версіяName відрізняється від моєї, вам потрібно змінити регулярний вираз і витягнути логіку деталей .


1

Наведені вище приклади не працюють з різних причин

Ось мій готовий до використання варіант, заснований на ідеях цієї статті:

android {
    compileSdkVersion 28

    // /programming/21405457

    def propsFile = file("version.properties")
    // Default values would be used if no file exist or no value defined
    def customAlias = "Alpha"
    def customMajor = "0"
    def customMinor = "1"
    def customBuild = "1" // To be incremented on release

    Properties props = new Properties()
    if (propsFile .exists())
        props.load(new FileInputStream(propsFile ))

    if (props['ALIAS'] == null) props['ALIAS'] = customAlias else customAlias = props['ALIAS']
    if (props['MAJOR'] == null) props['MAJOR'] = customMajor else customMajor = props['MAJOR']
    if (props['MINOR'] == null) props['MINOR'] = customMinor else customMinor = props['MINOR']
    if (props['BUILD'] == null) props['BUILD'] = customBuild else customBuild = props['BUILD']

    if (gradle.startParameter.taskNames.join(",").contains('assembleRelease')) {
        customBuild = "${customBuild.toInteger() + 1}"
        props['BUILD'] = "" + customBuild

        applicationVariants.all { variant ->
            variant.outputs.all { output ->
                if (output.outputFile != null && (output.outputFile.name == "app-release.apk"))
                    outputFileName = "app-${customMajor}-${customMinor}-${customBuild}.apk"
            }
        }
    }

    props.store(propsFile.newWriter(), "Incremental Build Version")

    defaultConfig {
        applicationId "org.example.app"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode customBuild.toInteger()
        versionName "$customAlias $customMajor.$customMinor ($customBuild)"

        ...
    }
...
}

0

Поваги до CommonsWare (Прийнятий відповідь) Paul Cantrell (Створіть файл, якщо його не існує) 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<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
}

0

За допомогою графіка завдань Gradle ми можемо перевірити / переключити тип збірки.

Основна ідея полягає у збільшенні версіїКод кожної збірки. На кожній побудові лічильника, що зберігається у файлі 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/

Дякуємо та з повагою!


0

Перший коментований код збільшить кількість під час кожного "Відновлення проекту" та збереже значення у файлі "Властивість версії".

Другий коментований код створить назву нової версії файлу APK під час "Створення APK-файлів".

android {
    compileSdkVersion 28
    buildToolsVersion "29.0.0"
    //==========================START==================================
    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)
    //===========================END===================================
    defaultConfig {
        applicationId "com.example.myapp"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "0.19"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            //=======================================START===============================================
            android.applicationVariants.all { variant ->
                variant.outputs.all {
                    def appName = "MyAppSampleName"
                    outputFileName = appName+"_v${variant.versionName}.${versionProps['VERSION_CODE']}.apk"
                }
            }
            //=======================================END===============================================
        }
    }
}

Додайте текст, який показує, що ви змінили. і чому
Метью

0

у версії Gradle 5.1.1 на mac ive змінив спосіб отримання назв завдань, і я все-таки намагався отримати аромат / тип збірки з build, але ледаче розбити назву завдання:

def versionPropsFile = file('version.properties')
if (versionPropsFile.canRead()) {
    def Properties versionProps = new Properties()

    versionProps.load(new FileInputStream(versionPropsFile))

    def value = 0

    def runTasks = gradle.getStartParameter().getTaskRequests().toString()

    if (runTasks.contains('assemble') || runTasks.contains('assembleRelease') || runTasks.contains('aR')) {
        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 {
        applicationId "de.evomotion.ms10"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode versionNumber
        versionName "${versionMajor}.${versionMinor}.${versionPatch} (${versionBuild})"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        signingConfig signingConfigs.debug
    }

} else {
    throw new GradleException("Could not read version.properties!")
}

код від @just_user цей


0

Є два рішення, які мені дуже подобаються. Перший залежить від Play Store, а другий - від Git.

Використовуючи Play Store, ви можете збільшити код версії, переглянувши найвищий доступний код завантаженої версії. Перевага цього рішення полягає в тому, що завантаження APK ніколи не вийде з ладу, оскільки код версії завжди на один вище, ніж усе, що є в Play Store. Мінусом є те, що розповсюдження APK за межами Play Store стає складнішим. Ви можете налаштувати це за допомогою Gradle Play Publisher, дотримуючись посібника із швидкого запуску та наказавши плагіну автоматично вирішувати коди версій :

plugins {
    id 'com.android.application'
    id 'com.github.triplet.play' version 'x.x.x'
}

android {
    ...
}

play {
    serviceAccountCredentials = file("your-credentials.json")
    resolutionStrategy = "auto"
}

Використовуючи Git, ви можете збільшити код версії залежно від кількості комісій та тегів у вашому сховищі. Перевага тут полягає в тому, що ваш результат відтворюється і не залежить від нічого, що знаходиться поза вашим репо. Мінус полягає в тому, що вам потрібно зробити нову фіксацію або тег, щоб збільшити код версії. Ви можете налаштувати це, додавши плагін Version Master Gradle :

plugins {
    id 'com.android.application'
    id 'com.supercilex.gradle.versions' version 'x.x.x'
}

android {
    ...
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.