Mã phiên bản tự động gia tăng với các thuộc tính bổ sung gradle


121

Tôi đang xây dựng một ứng dụng Android với gradle. Cho đến bây giờ tôi đã sử dụng tệp Manifest để tăng Mã phiên bản, nhưng tôi muốn đọc Mã phiên bản từ một tệp bên ngoài và tùy thuộc vào việc đó là phiên bản phát hành hay phiên bản gỡ lỗi sẽ tăng Mã phiên bản. Tôi đã thử các thuộc tính bổ sung, nhưng bạn không thể lưu chúng, có nghĩa là lần sau khi tôi xây dựng nó, tôi sẽ nhận được Mã phiên bản tương tự. Bất kỳ trợ giúp sẽ được rất nhiều đánh giá cao!

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

Xem câu trả lời của tôi tại đây: stackoverflow.com/a/33637600/348189
TacB0sS

Một lựa chọn khác (cách tiếp cận đặt và quên): medium.com/@passsy/…
Simon B.

Một lớp lót với sự lựa chọn của các plugin Gradle: stackoverflow.com/a/61718437/4548500
SUPERCILEX

Câu trả lời:


207

Tôi muốn đọc Mã phiên bản từ một tệp bên ngoài

Tôi chắc chắn rằng có bất kỳ giải pháp khả thi nào; đây là một:

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
}

Mã này yêu cầu một version.propertiestệp hiện có mà bạn sẽ tạo bằng tay trước khi có bản dựng đầu tiên VERSION_CODE=8.

Mã này chỉ đơn giản là chạm vào mã phiên bản trên mỗi bản dựng - bạn sẽ cần mở rộng kỹ thuật để xử lý mã phiên bản theo từng hương vị của mình.

Bạn có thể xem dự án mẫu Phiên bản trình bày mã này.


4
Làm cách nào để chỉ kích hoạt phiên bản này tăng dần trong khi tạo các bản phát hành?
Piotr

@Piotr: Nếu ý bạn là "chỉ tăng số lượng trên bản phát hành", điều đó có thể xảy ra, mặc dù tôi không biết chi tiết. Cá nhân tôi, vì có ~ 2 tỷ mã phiên bản có sẵn, tôi cho rằng mình sẽ không hết. :-)
CommonsWare

3
@Piotr bạn sẽ tạo một tác vụ làm tăng mã phiên bản một cách riêng biệt, sau đó thực hiện điều assembleRelease.finalizedBy incrementVersiongì đó tương tự hoặc tương tự. Tôi sẽ đăng mã của mình khi tôi đã chuẩn bị xong.
Chris.Jenkins

Sử dụng một tác vụ tùy chỉnh, bạn chỉ có thể làm một số việc như thế ./gradlew incrementVersionCode build. Các tác vụ được gọi tuần tự theo cách này sẽ dừng ngay khi bất kỳ tác vụ nào bị lỗi.
Dori

3
Như @ chris.jenkins vẫn tiding code của mình: p Đây là nêu trên trong công việc và form method gist.github.com/doridori/544c24509be236c11fd5 mà có thể được sử dụng bên trong DSL android vớiversionCode getIncrementingVersionCode()
Dori

83

Đây là một bản hiện đại hóa câu trả lời trước đây của tôi có thể được nhìn thấy bên dưới. Cái này đang chạy với Gradle 4.4Android Studio 3.1.1 .

Tập lệnh này làm gì:

  • Tạo tệp version.properties nếu không có (bỏ phiếu cho câu trả lời của Paul Cantrell bên dưới, đó là nơi tôi lấy ý tưởng nếu bạn thích câu trả lời này)
  • Đối với mỗi bản dựng, bản phát hành gỡ lỗi hoặc bất kỳ lúc nào bạn nhấn nút chạy trong Android Studio, số VERSION_BUILD sẽ tăng lên.
  • Mỗi khi bạn lắp ráp một phiên bản Android của bạn Mã phiên bản cho các cửa hàng chơi tăng và bạn số bản vá tăng.
  • Phần thưởng: Sau khi xây dựng xong, hãy sao chép apk của bạn để projectDir/apkdễ truy cập hơn.

Tập lệnh này sẽ tạo một số phiên bản giống v1.3.4 (123)và tạo một tệp apk như AppName-v1.3.4.apk .

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

Phiên bản chính: Phải được thay đổi thủ công để có những thay đổi lớn hơn.

Phiên bản nhỏ: Phải được thay đổi thủ công để có những thay đổi nhỏ hơn một chút.

Phiên bản vá: Tăng khi chạygradle assembleRelease

Phiên bản xây dựng: Tăng mỗi phiên bản

Số phiên bản: Giống như phiên bản Patch , đây là mã phiên bản mà Cửa hàng Play cần tăng cho mỗi lần tải lên apk mới.

Chỉ cần thay đổi nội dung trong các nhận xét có nhãn 1 - 3 bên dưới và tập lệnh sẽ thực hiện phần còn lại. :)

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

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

CÂU TRẢ LỜI BAN ĐẦU:

Tôi muốn tên phiên bản cũng tự động tăng. Vì vậy, đây chỉ là một bổ sung cho câu trả lời của CommonsWare đã hoạt động hoàn hảo đối với tôi. Đây là những gì làm việc cho tôi

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

BIÊN TẬP:

Vì tôi hơi lười biếng, tôi muốn phiên bản của mình hoạt động tự động nhất có thể. Điều tôi muốn là có một Phiên bản xây dựng tăng theo mỗi bản dựng, trong khi Số phiên bảnTên phiên bản chỉ tăng khi tôi tạo một bản dựng phát hành.

Đây là những gì tôi đã sử dụng trong năm qua, những điều cơ bản là từ câu trả lời của CommonsWare và câu trả lời trước đây của tôi, cộng với một số điều khác. Điều này dẫn đến phiên bản sau:

Tên phiên bản: 1.0.5 (123) -> Major.Minor.Patch (Build), Major và Minor được thay đổi thủ công.

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

    ...
}

...

Bản vá và mã phiên bản được tăng lên nếu bạn lắp ráp dự án của mình thông qua thiết bị đầu cuối với 'assembly' , 'assemblyRelease' hoặc 'aR' để tạo một thư mục mới trong gốc dự án của bạn có tên là apk / RELEASE, do đó bạn không phải xem qua bản dựng / đầu ra / more / more / more để tìm apk của bạn.

Thuộc tính phiên bản của bạn sẽ cần phải trông như thế này:

VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1

Rõ ràng là bắt đầu bằng 0. :)


2
Có thể loại bỏ 'variant.outputs.each {output ->' thứ hai, với '}' tương ứng.
redocoder

Điều này gây ra tất cả xây dựng của tôi là trong x86_64 mã gốc chỉ
Chisko

@Chisko Tôi nghi ngờ đoạn mã gradle này là nguyên nhân. Đặt một câu hỏi mới và chia sẻ mã điểm của bạn và chúng tôi có thể cố gắng tìm ra điều gì sai. :)
just_user

1
Bây giờ tôi có thể xác nhận đây không phải là nguyên nhân gốc rễ. Lời xin lỗi của tôi.
Chisko

1
@AlexanderGavriliuk là mã phiên bản được sử dụng bởi cửa hàng Play. Mã này liên tục cần tăng cho mỗi lần tải lên. Số bản vá có thể sẽ được đặt lại nếu bạn tăng phiên bản chính hoặc phụ. Không bao giờ được đặt lại số phiên bản nếu bạn tải ứng dụng lên cửa hàng Play với cùng tên gói.
just_user,

40

Một phiên bản thắt chặt hơn một chút của câu trả lời tuyệt vời của CommonsWare sẽ tạo tệp phiên bản nếu nó không tồn tại:

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
}

phần về cách tạo tệp phiên bản nếu nó không tồn tại ở đâu?
portfoliobuilder

4
if(versionPropsFile.exists())đảm bảo rằng nó không phát nổ nếu tệp không có ở đó. versionProps.store(versionPropsFile.newWriter(), null) ghi đè tệp bất kể nó đã tồn tại hay chưa.
Paul Cantrell

Phải kiểm tra những gì ?:có nghĩa là trong Groovy. Các nhà điều hành Elvis là một rút ngắn các nhà điều hành ternary.
Daniel

30

Tôi đã xem xét một vài tùy chọn để thực hiện việc này và cuối cùng quyết định đơn giản hơn là chỉ sử dụng thời gian hiện tại cho Mã phiên bản thay vì cố gắng tự động tăng Mã phiên bản và kiểm tra nó vào hệ thống kiểm soát sửa đổi của tôi.

Thêm phần sau vào của bạn 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
    }
}

Tuy nhiên, nếu bạn muốn tải lên các bản dựng sau năm 2696, bạn có thể muốn sử dụng một giải pháp khác.


2
Nếu bạn đang đọc này ngay bây giờ, và bắt đầu với một ứng dụng mới, bạn có thể trừ đi 1510351294:))
Entreco

tôi không hiểu !! bạn không sử dụng phân tích hoặc phân tích sự cố hoặc bất kỳ dịch vụ nào khác cung cấp dữ liệu với mã phiên bản và tên? và bạn đang chơi với những thứ này một cách dễ dàng?
Amir Ziarati 14/03/18

Nếu bạn có những tên phiên bản hợp lý, tôi nghĩ là ổn. Crashalytics cũng cung cấp tên phiên bản.
netcyrax

@emmby bạn lấy số '1451606400' từ đâu vậy? hoặc '1510351294' từ #Entreco Tôi đã cố gắng tính toán một cách vô ích!
Joseph Wambura

18

Một cách khác để nhận versionCodetự động là đặt versionCodesố lần cam kết trong gitnhánh đã kiểm tra . Nó hoàn thành các mục tiêu sau:

  1. versionCodeđược tạo tự động và nhất quán trên bất kỳ máy nào (bao gồm cả Continuous Integrationvà / hoặc Continuous Deploymentmáy chủ).
  2. Ứng dụng với điều này versionCodecó thể gửi lên GooglePlay.
  3. Không dựa vào bất kỳ tệp nào bên ngoài repo.
  4. Không đẩy bất cứ điều gì vào repo
  5. Có thể được ghi đè theo cách thủ công, nếu cần

Sử dụng thư viện gradle-git để thực hiện các mục tiêu trên. Thêm mã bên dưới vào build.gradletệp của bạn trong /appthư mục:

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
}

LƯU Ý: Để phương pháp này hoạt động, tốt nhất bạn chỉ nên triển khai tới Cửa hàng Google Play từ cùng một chi nhánh (ví dụ master:).


trong khi về bản chất là một giải pháp thanh lịch, tôi có thể tưởng tượng rằng điều này sẽ làm chậm thời gian xây dựng một cách đáng kể, tùy thuộc vào những gì chính xác đang xảy ra trong 2 dòng git. Bất kỳ kinh nghiệm về điều đó?
Hi vọng có ích

1
Tôi không nhận thấy bất kỳ sự cải thiện hiệu suất nào nếu bước này bị tắt. Đã sử dụng phương pháp cục bộ và trên các máy xây dựng của chúng tôi trong hơn một năm và hiệu suất không có vấn đề gì. Nếu bạn nhận thấy bất kỳ vấn đề hiệu suất nào, hãy cho tôi biết!
C0D3LIC1OU5

Mặc dù giải pháp của bạn là thanh lịch, nhưng nó có thể mang lại một số bất ngờ khó chịu. Điều quan trọng là Mã phiên bản luôn lớn hơn so với phiên bản trước. Điều gì sẽ xảy ra nếu bạn có một nhánh với 50 lần cam kết, và sau đó bạn tạo một nhánh khác mới hơn nhưng chỉ có 40 lần cam kết, có lẽ do quá nhiều lần cam kết từ một số tính năng đã hợp nhất. Tôi có thể thấy nhiều lý do khiến lịch sử cam kết của bạn không phải lúc nào cũng là một dòng tuyến tính của các cam kết gia tăng.
JHH

@JHH Những kết quả đó không nằm ngoài dự đoán. Như tôi đã đề cập trong một lưu ý, phương pháp này hoạt động tốt nhất khi triển khai từ cùng một nhánh.
C0D3LIC1OU5


10

Một tùy chọn khác, để tăng dấu versionCodeversionName, là sử dụng dấu thời gian.

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
}

Bắt đầu từ tháng 1, ngày 1 năm 2022 formattedDate = date.format ('yyMMddHHmm') vượt quá dung lượng của Số nguyên


1
Người đó muốn một số bản dựng tăng tự động
peter_pilgrim

6
@peter_pilgrim Caro là OP.
Đọc Ma-thi-ơ

Tôi nghĩ rằng đây là một giải pháp thanh lịch, nó không dựa vào các tệp có thể biến mất hoặc không hoặc sẽ liên tục hiển thị trong git. Nó cũng giúp bạn xác định duy nhất từng bản dựng trong ít nhất 22 năm tới.
Hi vọng có ích

trích dẫn developer.android.com:"Warning: Giá trị lớn nhất của Google Play cho phép mã phiên bản là 2100000000. "Vì vậy, cắt thực sự là năm 2021.
THS

Khắc phục sự cố giới hạn int: bỏ qua phút và sử dụng định dạng ngày 'yyMMddHH', mã phiên bản sẽ chứa ít nhất giờ.
Pointer Null

10

Để tăng phiên bản Mã chỉ trong phiên bản phát hành, hãy làm điều đó:

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
    }

mong đợi một hiện tại c://YourProject/app/version.properties tệp , mà bạn sẽ tạo bằng tay trước bản dựng đầu tiên để cóVERSION_CODE=8

Tệp tin version.properties:

VERSION_CODE=8


Thay vì đặt nó bên trong một nhiệm vụ và làm cho createReleaseBuildConfig phụ thuộc vào tác vụ đó.
lagos

versionName "1.0." + getSvnRevision () gây ra lỗi. Phương thức getSvnRevision () đang tham chiếu đến ở đâu? Bạn có chắc nó không phải là versionName "1.0." + Mã (tên phiên bản sẽ tăng theo mã phiên bản của bạn)?
portfoliobuilder

1
@portfoliobuilder, thay getSvnRevision () thành mã
NickUnuchek

4

Tạo tệp version.properties

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

Thay đổi 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
}

}

Đầu ra: 1.1.3.6


Cảm ơn. Và tại sao bạn lại chèn Mã phiên bản vào Tên phiên bản? Ngay cả ở vị trí thứ hai.
CoolMind

Nhưng nó sẽ giống như 1.71.3.76 chẳng hạn. Tôi nghĩ, tốt hơn là 1.3.76, tách nó khỏi mã phiên bản.
CoolMind

Đúng . bạn có thể thay đổi thành "$ {_ major} .. $ {_ minor}. $ {_ patch}. $ {_ versionCode}" hoặc xóa bản vá
Ahmad Aghazadeh

if (_major == 99) phải if (_minor == 99) ??
Anirudh Bagri

2

Xác định phiên bản Tên trongAndroidManifest.xml

android:versionName="5.1.5"

android{...}Khối bên trong ở build.gradlecấp ứng dụng:

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

android{...}Khối bên ngoài ở build.gradlecấp ứng dụng:

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
}

Sau khi tạo APK đã hát:

android:versionName="5.1.6"

Lưu ý: Nếu tên phiên bản của bạn khác với tên của tôi, bạn cần thay đổi regextrích xuất logic các bộ phận .


1

Các ví dụ hiển thị ở trên không hoạt động vì các lý do khác nhau

Đây là biến thể sẵn sàng sử dụng của tôi dựa trên ý tưởng từ bài viết này:

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

Tín dụng cho CommonsWare (Câu trả lời được chấp nhận) Paul Cantrell (Tạo tệp nếu tệp không tồn tại) ahmad aghazadeh (Tên và mã phiên bản)

Vì vậy, tôi đã trộn tất cả các ý tưởng của họ với nhau và đưa ra điều này. Đây là giải pháp kéo và thả chính xác những gì bài đăng đầu tiên yêu cầu.

Nó sẽ tự động cập nhật Mã phiên bản và Tên phiên bản theo trạng thái phát hành. Tất nhiên, bạn có thể di chuyển các biến xung quanh để phù hợp với nhu cầu của mình.

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

Sử dụng Gradle Task Graph, chúng ta có thể kiểm tra / chuyển đổi kiểu xây dựng.

Ý tưởng cơ bản là tăng Mã phiên bản trên mỗi bản dựng. Trên Mỗi bản dựng một bộ đếm được lưu trữ trong tệp version.properties . Nó sẽ được cập nhật trên mọi bản dựng APK mới và thay thế chuỗi versionCode trong tệp build.gradle bằng giá trị bộ đếm tăng dần này.

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

Đặt tập lệnh trên bên trong tệp build.gradle của mô-đun chính.

Tham khảo trang web: http://devdeeds.com/auto-increment-build-number-using-gradle-in-android/

Cảm ơn & Trân trọng!


0

Mã Nhận xét đầu tiên sẽ tăng số lượng trong mỗi "Dự án xây dựng lại" và lưu giá trị trong tệp "Thuộc tính Phiên bản".

Mã Nhận xét thứ hai sẽ tạo tên phiên bản mới của tệp APK trong khi "Tạo 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===============================================
        }
    }
}

Vui lòng thêm một số văn bản hiển thị những gì bạn đã thay đổi. và tại sao
Matthew Kerian

0

trong phiên bản Gradle 5.1.1 trên mac, tôi đã thay đổi cách các tên tác vụ được truy xuất, tôi đã cố gắng lấy hương vị / loại xây dựng từ bản dựng nhưng lại lười phân chia tên tác vụ:

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

mã là từ @just_user cái này


0

Có hai giải pháp tôi thực sự thích. Đầu tiên phụ thuộc vào Cửa hàng Play và thứ khác phụ thuộc vào Git.

Sử dụng Cửa hàng Play, bạn có thể tăng mã phiên bản bằng cách xem mã phiên bản tải lên cao nhất hiện có . Lợi ích của giải pháp này là tải lên APK sẽ không bao giờ bị lỗi vì mã phiên bản của bạn luôn cao hơn một so với bất kỳ mã phiên bản nào trên Cửa hàng Play. Nhược điểm là việc phân phối APK của bạn bên ngoài Cửa hàng Play trở nên khó khăn hơn. Bạn có thể thiết lập điều này bằng cách sử dụng Gradle Play Publisher bằng cách làm theo hướng dẫn bắt đầu nhanh và yêu cầu plugin tự động phân giải mã phiên bản :

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

android {
    ...
}

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

Sử dụng Git, bạn có thể tăng mã phiên bản dựa trên số lượng cam kết và thẻ mà kho lưu trữ của bạn có. Lợi ích ở đây là đầu ra của bạn có thể tái tạo và không phụ thuộc vào bất kỳ thứ gì bên ngoài kho lưu trữ của bạn. Nhược điểm là bạn phải thực hiện cam kết hoặc thẻ mới để tăng mã phiên bản của mình. Bạn có thể thiết lập điều này bằng cách thêm plugin Phiên bản Master Gradle :

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

android {
    ...
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.