Autoincrement VersionCode dengan properti ekstra gradle

121

Saya sedang membangun aplikasi Android dengan gradle. Sampai saat ini saya menggunakan file Manifest untuk meningkatkan versionCode, tetapi saya ingin membaca versionCode dari file eksternal dan tergantung apakah itu rilis flavor atau debug meningkatkan versionCode. Saya mencoba properti tambahan, tetapi Anda tidak dapat menyimpannya, yang berarti bahwa lain kali saya membuatnya, saya mendapatkan versionCode yang sama. Bantuan apa pun akan sangat dihargai!

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'
}
carvaq.dll
sumber
Lihat jawaban saya di sini: stackoverflow.com/a/33637600/348189
TacB0sS
Opsi lain (pendekatan set-and-forget): medium.com/@passsy/…
Simon B.
One-liner dengan pilihan plugin Gradle Anda: stackoverflow.com/a/61718437/4548500
SUPERCILEX

Jawaban:

207

Saya ingin membaca versionCode dari file eksternal

Saya yakin bahwa ada sejumlah solusi yang mungkin; ini satu:

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
}

Kode ini mengharapkan version.propertiesfile yang sudah ada , yang akan Anda buat dengan tangan sebelum membangun pertama VERSION_CODE=8.

Kode ini hanya meningkatkan kode versi pada setiap build - Anda perlu memperluas teknik untuk menangani kode versi per ragam Anda.

Anda dapat melihat proyek contoh Pembuatan Versi yang mendemonstrasikan kode ini.

CommonsWare
sumber
4
Bagaimana cara mengaktifkan peningkatan versi ini hanya saat membuat rilis build?
Piotr
@Piotr: Jika yang Anda maksud "hanya menambah angka pada rilis build", itu mungkin saja, meskipun saya tidak tahu detailnya. Secara pribadi, karena ada ~ 2 miliar kode versi yang tersedia, saya berasumsi bahwa saya tidak akan kehabisan. :-)
CommonsWare
3
@Piotr Anda akan membuat tugas yang menambahkan kode versi secara terpisah lalu melakukan sesuatu seperti assembleRelease.finalizedBy incrementVersionatau yang serupa. Saya akan memposting kode saya setelah saya merapikannya.
Chris.Jenkins
Menggunakan tugas khusus, Anda dapat melakukan sesuatu seperti ./gradlew incrementVersionCode build. Tugas yang dipanggil secara berurutan dengan cara ini akan berhenti segera setelah salah satu tugas gagal.
Dori
3
Karena @ chris.jenkins masih memberikan kodenya: p Berikut adalah di atas dalam bentuk tugas dan metode gist.github.com/doridori/544c24509be236c11fd5 yang dapat digunakan di dalam DSL android denganversionCode getIncrementingVersionCode()
Dori
83

Ini dia modernisasi jawaban saya sebelumnya yang dapat dilihat di bawah. Yang ini berjalan dengan Gradle 4.4 dan Android Studio 3.1.1 .

Apa yang dilakukan skrip ini:

  • Membuat file version.properties jika tidak ada (pilih jawaban Paul Cantrell di bawah ini, dari mana saya mendapat ide jika Anda menyukai jawaban ini)
  • Untuk setiap build, rilis debug, atau setiap kali Anda menekan tombol run di Android Studio, jumlah VERSION_BUILD meningkat.
  • Setiap kali Anda merakit rilis, versionCode Android Anda untuk play store meningkat dan nomor patch Anda meningkat.
  • Bonus: Setelah build selesai, salin apk Anda projectDir/apkagar lebih mudah diakses.

Skrip ini akan membuat nomor versi yang mirip v1.3.4 (123)dan membuat file apk seperti AppName-v1.3.4.apk .

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

Versi utama: Harus diubah secara manual untuk perubahan yang lebih besar.

Versi minor: Harus diubah secara manual untuk perubahan yang sedikit lebih kecil.

Versi patch: Meningkat saat dijalankangradle assembleRelease

Versi build: Meningkatkan setiap build

Nomor Versi: Sama seperti versi Patch , ini untuk kode versi yang perlu ditingkatkan oleh Play Store untuk setiap unggahan apk baru.

Ubah saja konten di komentar berlabel 1 - 3 di bawah dan skrip akan melakukan sisanya. :)

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

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

JAWABAN AWAL:

Saya ingin versionName meningkat secara otomatis juga. Jadi ini hanyalah tambahan dari jawaban CommonsWare yang bekerja dengan sempurna untuk saya. Inilah yang berhasil untuk saya

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

EDIT:

Karena saya agak malas, saya ingin pembuatan versi saya bekerja secara otomatis. Yang saya inginkan adalah memiliki Versi Build yang bertambah dengan setiap build, sedangkan Nomor Versi dan Nama Versi hanya meningkat ketika saya membuat build rilis.

Inilah yang telah saya gunakan selama setahun terakhir, dasar-dasarnya berasal dari jawaban CommonsWare dan jawaban saya sebelumnya, ditambah lagi. Ini menghasilkan versi berikut:

Nama Versi: 1.0.5 (123) -> Major.Minor.Patch (Build), Major dan Minor diubah secara manual.

Dalam 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 dan versionCode ditingkatkan jika Anda merakit proyek Anda melalui terminal dengan 'assemble' , 'assembleRelease' atau 'aR' yang membuat folder baru di root proyek Anda yang disebut apk / RELEASE sehingga Anda tidak perlu melihat-lihat build / outputs / more / more / more untuk menemukan apk Anda.

Properti versi Anda harus terlihat seperti ini:

VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1

Jelas dimulai dengan 0. :)

just_user
sumber
2
'Variant.outputs.each {output ->' kedua dapat dihapus, dengan '}' yang sesuai.
redocoder
Ini menyebabkan semua bangunan saya hanya dalam kode asli x86_64
Chisko
@ Chisko Saya ragu bagian dari kode gradle ini adalah penyebabnya. Ajukan pertanyaan baru dan bagikan kode gradle Anda dan kami dapat mencoba mencari tahu apa yang salah. :)
just_user
1
Sekarang saya dapat memastikan bahwa ini bukanlah penyebab utamanya. Permintaan maaf saya.
Chisko
1
@AlexanderGavriliuk adalah kode versi yang digunakan oleh play store yang terus-menerus perlu ditingkatkan untuk setiap unggahan. Nomor patch mungkin akan disetel ulang jika Anda meningkatkan versi mayor atau minor. Nomor versi tidak boleh, tidak akan pernah bisa disetel ulang jika Anda mengunggah aplikasi ke play store dengan nama paket yang sama.
just_user
40

Versi yang sedikit diperketat dari jawaban luar biasa CommonsWare membuat file versi jika tidak ada:

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
}
Paul Cantrell
sumber
Di manakah bagian tentang membuat file versi jika tidak ada?
portfoliobuilder
4
if(versionPropsFile.exists())memastikan bahwa itu tidak meledak jika file tidak ada. versionProps.store(versionPropsFile.newWriter(), null) menimpa file terlepas dari apakah file itu sudah ada.
Paul Cantrell
Harus memeriksa apa yang ?:dimaksud dengan Groovy. The Operator Elvis adalah pemendekan operator ternary.
Daniel
30

Saya melihat beberapa opsi untuk melakukan ini, dan akhirnya memutuskan bahwa lebih mudah menggunakan waktu saat ini untuk versionCode daripada mencoba menaikkan versionCode secara otomatis dan memeriksanya ke dalam sistem kontrol revisi saya.

Tambahkan yang berikut ini ke Anda 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
    }
}

Namun, jika Anda ingin mengupload build setelah tahun 2696, Anda mungkin ingin menggunakan solusi yang berbeda.

emmby
sumber
2
Jika Anda membaca ini sekarang, dan memulai dengan aplikasi baru, Anda dapat mengurangi 1510351294:))
Entreco
saya tidak mengerti ini !! tidakkah Anda menggunakan analitik atau crashlytics atau layanan lain yang memberikan data dengan kode versi dan nama? dan kamu memainkan ini dengan mudah?
Amir Ziarati
Jika Anda memiliki nama versi yang masuk akal, saya rasa tidak apa-apa. Crashalytics juga menyediakan nama versi.
netcyrax
@ emmby dari mana Anda mendapatkan nomor '1451606400'? atau '1510351294' dari #Entreco yang telah saya coba hitung dengan sia-sia!
Joseph Wambura
18

Cara lain untuk mendapatkan secara versionCodeotomatis adalah mengatur versionCodejumlah komit di gitcabang yang diperiksa . Itu mencapai tujuan berikut:

  1. versionCodedibuat secara otomatis dan konsisten pada mesin apa pun (termasuk a Continuous Integrationdan / atauContinuous Deployment server ).
  2. Aplikasi dengan ini versionCode dapat dikirim ke GooglePlay.
  3. Tidak bergantung pada file apa pun di luar repo.
  4. Tidak mendorong apa pun ke repo
  5. Dapat diganti secara manual, jika perlu

Menggunakan pustaka gradle-git untuk mencapai tujuan di atas. Tambahkan kode di bawah ini ke build.gradlefile Anda /appdirektori:

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
}

CATATAN: Agar metode ini berfungsi, yang terbaik adalah hanya menerapkan ke Google Play Store dari cabang yang sama (mis. master).

C0D3LIC1OU5
sumber
sementara pada dasarnya adalah solusi yang elegan, saya dapat membayangkan bahwa ini akan memperlambat waktu pembuatan secara drastis, tergantung pada apa yang sebenarnya terjadi di 2 baris git. Ada pengalaman tentang itu?
Semoga
1
Saya tidak melihat adanya peningkatan kinerja jika langkah ini dinonaktifkan. Telah menggunakan metode secara lokal dan pada mesin build kami selama lebih dari setahun dan kinerja tidak menjadi masalah apa pun. Jika Anda melihat ada masalah kinerja, beri tahu saya!
C0D3LIC1OU5
Meskipun solusi Anda elegan, ini dapat memberikan beberapa kejutan tak terduga yang tidak menyenangkan. Sangat penting bahwa versionCodes selalu lebih besar dari pada rilis sebelumnya. Bagaimana jika Anda memiliki satu cabang dengan 50 komit, dan Anda kemudian membuat cabang lain yang lebih baru tetapi hanya memiliki 40 komit, mungkin karena menekan sejumlah komit dari beberapa fitur gabungan. Saya dapat melihat banyak alasan mengapa riwayat komit Anda tidak selalu menjadi aliran linier dari komit tambahan.
JHH
@JHH Hasil tersebut tidak terduga. Seperti yang saya sebutkan dalam catatan, metode ini berfungsi paling baik saat menerapkan dari cabang yang sama.
C0D3LIC1OU5
13

Baru-baru ini saya sedang mengerjakan plugin gradle untuk Android yang membuat versionCode dan versionName secara otomatis. ada banyak penyesuaian. di sini Anda dapat menemukan info lebih lanjut tentang itu https://github.com/moallemi/gradle-advanced-build-version

moallemi
sumber
Ini adalah plugin yang bagus! Terima kasih telah berbagi 🙂
Cory Robinson
10

Opsi lain, untuk menambah versionCodedan versionName, menggunakan stempel waktu.

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
}

Mulai Januari, 1 2022 formattedDate = date.format ('yyMMddHHmm') melebihi kapasitas Integer

carvaq.dll
sumber
1
Orang tersebut menginginkan nomor build penambah otomatis
peter_pilgrim
6
@peter_pilgrim Caro adalah OP.
Matius Baca
Menurut saya ini adalah solusi yang elegan, tidak bergantung pada file yang mungkin hilang atau tidak atau yang akan terus muncul di git. Ini juga membantu Anda mengidentifikasi secara unik setiap bangunan untuk setidaknya selusin 22 tahun ke depan.
Semoga
mengutip developer.android.com:"Warning: Nilai terbesar Google Play memungkinkan untuk versionCode adalah 2100000000. "Jadi, cutoff sebenarnya 2021.
THS
Perbaiki untuk batas int: hilangkan menit dan gunakan format tanggal 'yyMMddHH', kode versi akan berisi setidaknya jam.
Pointer Null
10

Untuk menaikkan versionCode hanya dalam versi rilis lakukan:

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
    }

mengharapkan c://YourProject/app/version.propertiesfile yang ada , yang akan Anda buat dengan tangan sebelum membangun pertamaVERSION_CODE=8

File version.properties:

VERSION_CODE=8

NickUnuchek
sumber
Alih-alih, letakkan di dalam tugas dan buat generateReleaseBuildConfig bergantung pada tugas itu.
lagos
versionName "1.0." + getSvnRevision () menyebabkan kesalahan. Di mana metode getSvnRevision () merujuk? Apakah Anda yakin itu seharusnya bukan versionName "1.0." + Kode (nama versi akan bertambah dengan kode versi Anda)?
portfoliobuilder
1
@portfoliobuilder, ganti getSvnRevision () ke kode
NickUnuchek
4

Buat file version.properties

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

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

}

Keluaran: 1.1.3.6

Ahmad Aghazadeh
sumber
Terima kasih. Dan mengapa Anda memasukkan versionCode ke versionName? Bahkan di posisi kedua.
CoolMind
Tapi akan terlihat seperti 1.71.3.76, misalnya. Saya pikir, lebih baik adalah 1.3.76, memisahkannya dari kode versi.
CoolMind
Iya . Anda dapat mengubah ke "$ {_ major} .. $ {_ minor}. $ {_ patch}. $ {_ versionCode}" atau menghapus patch
Ahmad Aghazadeh
if (_major == 99) harus if (_minor == 99) ??
Anirudh Bagri
2

Tentukan versionName dalamAndroidManifest.xml

android:versionName="5.1.5"

Di dalam android{...}blok di build.gradletingkat aplikasi:

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

android{...}Blok luar di build.gradletingkat aplikasi:

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
}

Setelah membuat APK hangus:

android:versionName="5.1.6"

Catatan: Jika versionName Anda berbeda dari my, Anda perlu mengubah regex dan mengekstrak logika bagian .

Sergey Shustikov
sumber
1

Contoh yang ditunjukkan di atas tidak berfungsi karena alasan yang berbeda

Berikut adalah varian siap pakai saya berdasarkan ide dari artikel ini:

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

        ...
    }
...
}
Alexander Gavriliuk
sumber
0

Penghargaan untuk CommonsWare (Jawaban yang Diterima) Paul Cantrell (Buat file jika tidak ada) ahmad aghazadeh (Nama versi dan kode)

Jadi saya menggabungkan semua ide mereka dan menghasilkan ini. Ini adalah solusi seret dan lepas untuk apa yang ditanyakan oleh posting pertama.

Ini akan secara otomatis memperbarui versionCode dan versionName sesuai dengan status rilis. Tentu saja Anda dapat memindahkan variabel untuk menyesuaikan dengan kebutuhan Anda.

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
}
Petir
sumber
0

Menggunakan Gradle Task Graph kita dapat memeriksa / mengganti tipe build.

Ide dasarnya adalah menaikkan versionCode pada setiap build. Di Setiap build penghitung yang disimpan dalam file version.properties . Ini akan terus diupdate pada setiap versi APK baru dan mengganti string versionCode dalam file build.gradle dengan nilai penghitung yang bertambah ini.

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

Tempatkan skrip di atas di dalam file build.gradle modul utama Anda.

Situs Referensi: http://devdeeds.com/auto-increment-build-number-using-gradle-in-android/

Terima kasih & Salam!

Jayakrishnan
sumber
0

Kode First Commented akan menambah angka sementara setiap "Rebuild Project" dan menyimpan nilainya di file "Version Property".

Kode Kedua Berkomentar akan menghasilkan nama versi baru dari file APK sementara "Membangun 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===============================================
        }
    }
}
Radha Krishna Eedulakanti
sumber
Harap tambahkan beberapa teks yang menunjukkan apa yang telah Anda ubah. dan mengapa
Matthew Kerian
0

dalam versi Gradle 5.1.1 di mac ive mengubah cara pengambilan nama tugas, meskipun saya mencoba mendapatkan ragam / jenis build dari build tetapi malas untuk membagi nama tugas:

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

kode ini dari @just_user yang ini

Basur
sumber
0

Ada dua solusi yang sangat saya suka. Yang pertama bergantung pada Play Store dan yang lainnya bergantung pada Git.

Dengan menggunakan Play Store, Anda dapat menaikkan kode versi dengan melihat kode versi unggahan tertinggi yang tersedia . Manfaat dari solusi ini adalah bahwa unggahan APK tidak akan pernah gagal karena kode versi Anda selalu lebih tinggi dari apa pun yang ada di Play Store. Sisi negatifnya adalah mendistribusikan APK Anda di luar Play Store menjadi lebih sulit. Anda dapat menyiapkannya menggunakan Gradle Play Publisher dengan mengikuti panduan memulai dan memberi tahu plugin untuk menyelesaikan kode versi secara otomatis :

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

android {
    ...
}

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

Dengan menggunakan Git, Anda dapat menaikkan kode versi berdasarkan berapa banyak komit dan tag yang dimiliki repositori Anda. Manfaatnya di sini adalah bahwa keluaran Anda dapat direproduksi dan tidak bergantung pada apa pun di luar repo Anda. Kelemahannya adalah Anda harus membuat commit atau tag baru untuk mendapatkan kode versi Anda. Anda dapat menyiapkannya dengan menambahkan plugin Version Master Gradle :

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

android {
    ...
}
SUPERCILEX
sumber