Làm cách nào để đặt versionName trong tên tệp APK bằng gradle?


169

Tôi đang cố gắng đặt số phiên bản cụ thể trong tên tệp APK được tạo tự động.

Bây giờ gradle tạo ra myapp-release.apknhưng tôi muốn nó trông giống như thế myapp-release-1.0.apk.

Tôi đã thử đổi tên tùy chọn có vẻ lộn xộn. Có một cách đơn giản để làm điều này?

buildTypes {
    release {
       signingConfig signingConfigs.release
       applicationVariants.each { variant ->
       def file = variant.outputFile
       variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" +    defaultConfig.versionName + ".apk"))
    }
}

Tôi đã thử mã ở trên mà không có may mắn. Bất kỳ đề xuất? (sử dụng lớp 1.6)

Câu trả lời:


225

Tôi chỉ phải thay đổi tên phiên bản ở một nơi. Mã cũng đơn giản.

Các ví dụ dưới đây sẽ tạo các tệp apk có tên MyCompany-MyAppName-1.4.8-debug.apk hoặc MyCompany-MyAppName-1.4.8-release.apk tùy thuộc vào biến thể xây dựng được chọn.

Lưu ý rằng giải pháp này hoạt động trên cả Gói APK và Gói ứng dụng (tệp .aab) .

Xem thêm: Cách thay đổi tên tệp ánh xạ proguard trong lớp cho dự án Android

Giải pháp cho Plugin Gradle gần đây

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"
    defaultConfig {
        applicationId "com.company.app"
        minSdkVersion 13
        targetSdkVersion 21
        versionCode 14       // increment with every release
        versionName '1.4.8'   // change with every release
        setProperty("archivesBaseName", "MyCompany-MyAppName-$versionName")
    }
}

Giải pháp trên đã được thử nghiệm với các Phiên bản Plugin Android Gradle sau:

  • 3.5.2 (tháng 11 năm 2019)
  • 3.3.0 (tháng 1 năm 2019)
  • 3.1.0 (Tháng 3 năm 2018)
  • 3.0.1 (tháng 11 năm 2017)
  • 3.0.0 (tháng 10 năm 2017)
  • 2.3.2 (tháng 5 năm 2017)
  • 2.3.1 (tháng 4 năm 2017)
  • 2.3.0 (tháng 2 năm 2017)
  • 2.2.3 (tháng 12 năm 2016)
  • 2.2.2
  • 2.2.0 (tháng 9 năm 2016)
  • 2.1.3 (tháng 8 năm 2016)
  • 2.1.2
  • 2.0.0 (tháng 4 năm 2016)
  • 1.5.0 (2015/11/12)
  • 1.4.0-beta6 (2015/10/05)
  • 1.3.1 (2015/08/11)

Tôi sẽ cập nhật bài viết này khi các phiên bản mới ra mắt.

Giải pháp chỉ được thử nghiệm trên các phiên bản 1.1.3-1.3.0

Giải pháp sau đây đã được thử nghiệm với Phiên bản Plugin Android Gradle sau:

tập tin lớp ứng dụng:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"
    defaultConfig {
        applicationId "com.company.app"
        minSdkVersion 13
        targetSdkVersion 21
        versionCode 14       // increment with every release
        versionName '1.4.8'   // change with every release
        archivesBaseName = "MyCompany-MyAppName-$versionName"
    }
}

11
Tôi nghĩ rằng đây là cách tiếp cận phù hợp thay vì viết một nhiệm vụ khác để đổi tên các tập tin.
Nandish A

5
chỉ cần thay đổi thành archivesBaseName = "MyCompany-MyAppName- $ versionName" nếu bạn có OCD và không muốn AS cảnh báo bạn về +
ligi

4
Tìm kiếm tuyệt vời, nhưng không hoạt động tốt với các hương vị với các mã phiên bản khác nhau. Tất cả đều kết thúc với cùng một mã phiên bản.
weston

2
Có cách nào để thêm variant.buildType.namevào tên? Tôi biết điều này không thực sự liên quan đến cấu hình mặc định, nhưng tôi đang cố gắng tìm ra cách loại bỏ variantOutput.getAssemble()cảnh báo lỗi thời
Allan W

2
Có thể xóa khỏi tên apk cuối cùng '-debug' / '-release' không?
ilyamuromets

173

Điều này đã giải quyết vấn đề của tôi: sử dụng applicationVariants.allthay vìapplicationVariants.each

buildTypes {
      release {
        signingConfig signingConfigs.release
        applicationVariants.all { variant ->
            def file = variant.outputFile
            variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk")) 
        }
    }       
}

Cập nhật:

Vì vậy, có vẻ như điều này không hoạt động với 0.14+ phiên bản plugin gradle android studio.

Đây là mẹo (Tham khảo từ câu hỏi này ):

android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.outputFile = new File(
                    output.outputFile.parent,
                    output.outputFile.name.replace(".apk", "-${variant.versionName}.apk"))
        }
    }
}

3
Bạn có biết làm thế nào để nó hoạt động nếu tôi có một versionNameđịnh nghĩa AndroidManifest.xmlthay vì cấu hình gradle không? Nó cho tôi myapp-release-null.apkbây giờ.
Iwo Banas

1
Câu trả lời này không hoạt động với 0,14+ phiên bản của plugin gradle. Bất kỳ cập nhật để làm việc với những người?
Argyle

1
@without class Tôi đã hỏi đây là câu hỏi của chính mình và đã trả lời nó ở đây: stackoverflow.com/questions/27068505/ợi
Argyle

2
Đối với những người cập nhật lên Lớp 4: thay đổi eachthành alloutput.outputFilethành outputFileName. Nếu ai đó thú nhận điều này hoạt động, nó có thể được chỉnh sửa thành câu trả lời :)
PHPirate

6
@PHPirate: gần như hoạt động:Error:(34, 0) Cannot set the value of read-only property 'name'
Vịt Mooing

47

(EDITED hoạt động với Android Studio 3.0 và Gradle 4)

Tôi đang tìm kiếm một tùy chọn đổi tên apk apk phức tạp hơn và tôi đã viết cái này với hy vọng nó hữu ích cho bất kỳ ai khác. Nó đổi tên apk với dữ liệu sau:

  • hương vị
  • kiểu xây dựng
  • phiên bản
  • ngày

Nó đã cho tôi một chút nghiên cứu trong các lớp học và một chút sao chép / dán từ các câu trả lời khác. tôi đang dùng lớp 3.1.3 .

Trong bản dựng.gradle:

android {

    ...

    buildTypes {
        release {
            minifyEnabled true
            ...
        }
        debug {
            minifyEnabled false
        }
    }

    productFlavors {
        prod {
            applicationId "com.feraguiba.myproject"
            versionCode 3
            versionName "1.2.0"
        }
        dev {
            applicationId "com.feraguiba.myproject.dev"
            versionCode 15
            versionName "1.3.6"
        }
    }

    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def project = "myProject"
            def SEP = "_"
            def flavor = variant.productFlavors[0].name
            def buildType = variant.variantData.variantConfiguration.buildType.name
            def version = variant.versionName
            def date = new Date();
            def formattedDate = date.format('ddMMyy_HHmm')

            def newApkName = project + SEP + flavor + SEP + buildType + SEP + version + SEP + formattedDate + ".apk"

            outputFileName = new File(newApkName)
        }
    }
}

Nếu bạn biên dịch ngày hôm nay (13-10-2016) lúc 10:47, bạn sẽ nhận được các tên tệp sau tùy thuộc vào hương vị và kiểu xây dựng mà bạn đã chọn:

  • gỡ lỗi dev : myProject_ dev_debug_1.3.6 _131016_1047.apk
  • phát hành dev : myProject_ dev_release_1.3.6 _131016_1047.apk
  • gỡ lỗi prod : myProject_ prod_debug_1.2.0 _131016_1047.apk
  • phát hành prod : myProject_ prod_release_1.2.0 _131016_1047.apk

Lưu ý: tên apk phiên bản chưa được phân bổ vẫn là tên mặc định.


Giải pháp tuyệt vời. Tôi đã thử nó, và nó là hoàn hảo cho vấn đề của tôi. Cảm ơn!
Pabel

có thể sử dụng cách tiếp cận tương tự trong Xamarin Studio không?
Alessandro Caliaro

Sẽ thật tuyệt nếu điều đó là có thể, nhưng tôi đang bắt đầu ngay một khóa học Xamarin và tôi vẫn chưa đủ thực hành với nó để biết liệu nó có thể hay không. Tôi sẽ hỏi câu hỏi này và đến đây một lần nữa.
Fer

Nhận xét từ giáo viên của khóa học: "có một tùy chọn trong đó bạn có thể sử dụng các lệnh để thay đổi tên của các tệp được tạo". Do đó, cách tiếp cận để sử dụng từ Xamarin phải khác với cách tôi đã viết cho Android Studio, xin lỗi.
Fer

3
Để giải quyết các lỗi không thể thiết lập giá trị của bất động sản 'outputFile' chỉ đọc - như đã đề cập trong một bài bình luận trước đó cho phải "thay đổi eachđến alloutput.outputFileđể outputFileName" - bài này cung cấp một số chi tiết trên rằng: stackoverflow.com/a/44265374/2162226
Gene Bo

18

Tóm lại, đối với những người không biết cách nhập gói trong build.gradle(như tôi), hãy sử dụng cách sau buildTypes,

buildTypes {
      release {
        signingConfig signingConfigs.release
        applicationVariants.all { variant ->
            def file = variant.outputFile
            def manifestParser = new com.android.builder.core.DefaultManifestParser()
            variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile) + ".apk")) 
        }
    }       
}

===== CHỈNH SỬA =====

Nếu bạn đặt versionCodeversionNametrong build.gradletệp của bạn như thế này:

defaultConfig {
    minSdkVersion 15
    targetSdkVersion 19
    versionCode 1
    versionName "1.0.0"
}

Bạn nên đặt nó như thế này:

buildTypes {   
        release {
            signingConfig signingConfigs.releaseConfig
            applicationVariants.all { variant ->
                def file = variant.outputFile
                variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
            }
        }
}


====== CHỈNH SỬA với Android Studio 1.0 ======

Nếu bạn đang sử dụng Android Studio 1.0, bạn sẽ gặp một lỗi như thế này:

Error:(78, 0) Could not find property 'outputFile' on com.android.build.gradle.internal.api.ApplicationVariantImpl_Decorated@67e7625f.

Bạn nên thay đổi build.Typesmột phần để này:

buildTypes {
        release {
            signingConfig signingConfigs.releaseConfig
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    output.outputFile = new File(output.outputFile.parent, output.outputFile.name.replace(".apk", "-" + defaultConfig.versionName + ".apk"))
                }
            }
        }
    }

Điều này làm việc tuyệt vời. Tuy nhiên, vì tôi tăng phiên bản kê khai của mình trong bản dựng lớp, nó sẽ tạo ra một APK có giá trị cũ hơn (tăng trước). Bất kỳ cách nào để đảm bảo điều này sẽ ảnh hưởng sau khi tập lệnh phân lớp tăng số phiên bản?
Chàng trai

1
@Guy Xin lỗi mất quá lâu. Tôi chỉnh sửa câu trả lời, xem nó có thể giải quyết vấn đề của bạn không.
Wesley

17

Nếu bạn không chỉ định versionName trong khối defaultConfig thì defaultConfig.versionNamesẽ dẫn đếnnull

để lấy versionName từ tệp kê khai, bạn có thể viết mã sau trong build.gradle:

import com.android.builder.DefaultManifestParser

def manifestParser = new DefaultManifestParser()
println manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)

7
Tôi tin rằng với các phiên bản sau của gradle, giờ đây là com.android.builder.core.DefaultManifestParser
Ryan S

8

Trong trường hợp của tôi, tôi chỉ muốn tìm cách tự động hóa việc tạo ra các apktên releasedebugbiến thể khác nhau. Tôi đã xoay sở để làm điều này một cách dễ dàng bằng cách đặt đoạn trích này như một đứa trẻ của android:

applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def appName = "My_nice_name_"
        def buildType = variant.variantData.variantConfiguration.buildType.name
        def newName
        if (buildType == 'debug'){
            newName = "${appName}${defaultConfig.versionName}_dbg.apk"
        } else {
            newName = "${appName}${defaultConfig.versionName}_prd.apk"
        }
        output.outputFile = new File(output.outputFile.parent, newName)
    }
}

Đối với plugin Android grad 3.0.0 mới, bạn có thể làm một cái gì đó như thế:

 applicationVariants.all { variant ->
    variant.outputs.all {
        def appName = "My_nice_name_"
        def buildType = variant.variantData.variantConfiguration.buildType.name
        def newName
        if (buildType == 'debug'){
            newName = "${appName}${defaultConfig.versionName}_dbg.apk"
        } else {
            newName = "${appName}${defaultConfig.versionName}_prd.apk"
        }
        outputFileName = newName
    }
}

Điều này tạo ra một cái gì đó như: My_nice_name_3.2.31_dbg.apk


6

Một cách khác là sử dụng như sau:

String APK_NAME = "appname"
int VERSION_CODE = 1
String VERSION_NAME = "1.0.0"

project.archivesBaseName = APK_NAME + "-" + VERSION_NAME;

    android {
      compileSdkVersion 21
      buildToolsVersion "21.1.1"

      defaultConfig {
        applicationId "com.myapp"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode VERSION_CODE
        versionName VERSION_NAME
      }

       .... // Rest of your config
}

Điều này sẽ đặt "appname-1.0.0" cho tất cả các đầu ra apk của bạn.


Xin lỗi không hoạt động (lâu hơn nữa): No such property: archivesBaseName for class: org.gradle.api.internal.project.DefaultProject_Decorated
Martin

Bạn đang sử dụng phiên bản lớp nào?
Marco RS

6

Lớp 6+

Tôi hiện đang sử dụng các tính năng sau trong Android Studio 4.0 và Lớp 6.4:

android {
    defaultConfig {
        applicationId "com.mycompany.myapplication"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 15
        versionName "2.1.1"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            applicationVariants.all { variant ->
                variant.outputs.all {
                    outputFileName = "ApplicationName-${variant.name}-${variant.versionName}.apk"
                }
            }
        }
    }
}

Lớp 4

Cú pháp đã thay đổi một chút trong Lớp 4 (Android Studio 3+) (từ output.outputFileđến outputFileName, ý tưởng từ câu trả lời này là ngay bây giờ:

android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def newName = outputFileName
            newName.replace(".apk", "-${variant.versionName}.apk")
            outputFileName = new File(newName)
        }
    }
}

Bất kỳ ý tưởng làm thế nào để sửa lỗi này cho lớp 6?
spartygw

@spartygw Cập nhật câu trả lời
PHPirate

5

Cách đúng để đổi tên apk, theo câu trả lời @Jon

defaultConfig {
        applicationId "com.irisvision.patientapp"
        minSdkVersion 24
        targetSdkVersion 22
        versionCode 2  // increment with every release
        versionName "0.2" // change with every release
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        //add this line
        archivesBaseName = "AppName-${versionName}-${new Date().format('yyMMdd')}"
    }   

Hoặc một cách khác bạn có thể đạt được kết quả tương tự với

android {
    ...

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def formattedDate = new Date().format('yyMMdd')
            outputFileName = "${outputFileName.replace(".apk","")}-v${defaultConfig.versionCode}-${formattedDate}.apk"
        }
    }
}

Đẹp về điều này! Tôi thích điều này tốt hơn những cách khác mà tôi hiện đang làm điều này.
Droid Chris

3

Có nhiều câu trả lời đúng hoặc đầy đủ hoặc sau một số sửa đổi. Nhưng dù sao tôi cũng sẽ thêm phần của mình vì tôi gặp vấn đề với tất cả chúng vì tôi đang sử dụng tập lệnh để tạo VersionName và VersionCode một cách linh hoạt bằng cách nối vàopreBuild tác vụ.

Nếu bạn đang sử dụng một số cách tiếp cận tương tự thì đây là mã sẽ hoạt động:

project.android.applicationVariants.all { variant ->
    variant.preBuild.doLast {
    variant.outputs.each { output ->
        output.outputFile = new File(
                output.outputFile.parent,
                output.outputFile.name.replace(".apk", "-${variant.versionName}@${variant.versionCode}.apk"))
        }
    }
}

Để giải thích: Vì tôi ghi đè mã phiên bản và tên trong hành động đầu tiên của preBuild tôi phải thêm đổi tên tệp vào cuối nhiệm vụ này. Vì vậy, lớp sẽ làm gì trong trường hợp này là:

Tiêm mã phiên bản / tên-> thực hiện các hành động preBuild -> thay thế tên cho apk


Bạn đang đặt các biến versionCode và versionName được tạo ở đâu?
Sao Hỏa

Như tôi nhớ điều đó đã được thực hiện bên trong plugin gradle tùy chỉnh của chúng tôi. Việc thực thi của nó được gọi là hành động cuối cùng của nhiệm vụ preBuild.
Igor ordaš

2
    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            output.outputFileName = output.outputFileName.replace(".apk", "-${variant.versionName}.apk")
        }
    }

Mặc dù đoạn mã này có thể giải quyết câu hỏi, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn.
Rosário Pereira Fernandes

1

Trong trường hợp của tôi, tôi giải quyết lỗi này theo cách này

thêm SUFFIX vào phiên bản Gỡ lỗi, trong trường hợp này tôi thêm văn bản "-DEBUG" vào triển khai Gỡ lỗi của mình

 buildTypes {
        release {

            signingConfig signingConfigs.release
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'


        }
        debug {

            defaultConfig {
                debuggable true

                versionNameSuffix "-DEBUG"
            }
        }
    }

Điều này không thay đổi tên tệp APK.
Tom

1
Đây là một mẹo hay, thực sự. Không phải trong câu hỏi đúng, nhưng một trong những tốt. Tôi có thể đọc thêm về nó ở đâu? Có thể sử dụng versionNameSuffixdựa trên chi nhánh GIT? Ví dụ: nếu không phải là "chính chủ", luôn có hậu tố, ngay cả khi đó là phiên bản phát hành
nhà phát triển Android

0

Đối với các phiên bản lớp mới nhất, bạn có thể sử dụng đoạn mã sau:

Đặt vị trí tệp kê khai ứng dụng của bạn trước

 sourceSets {
        main {
            manifest.srcFile 'src/main/AndroidManifest.xml'
        {
    }

Và sau này trong build.gradle

import com.android.builder.core.DefaultManifestParser

def getVersionName(manifestFile) {
    def manifestParser = new DefaultManifestParser();
    return manifestParser.getVersionName(manifestFile);
}

def manifestFile = file(android.sourceSets.main.manifest.srcFile);
def version = getVersionName(manifestFile)

buildTypes {
    release {
       signingConfig signingConfigs.release
       applicationVariants.each { variant ->
       def file = variant.outputFile
       variant.outputFile = new File(file.parent, file.name.replace(".apk", "-" +    versionName + ".apk"))
    }
}

Điều chỉnh nếu bạn có các biểu hiện khác nhau cho mỗi loại bản dựng. nhưng vì tôi có một cái duy nhất - hoạt động hoàn hảo cho tôi.


Có thể thêm một chuỗi từ một tệp lớp vào tên apk ??
Upendra Shah

0

Tính đến Android Studio 1.1.0, tôi thấy sự kết hợp này làm việc trong android cơ thể của build.gradletập tin. Đây là nếu bạn không thể tìm ra cách nhập dữ liệu tệp xml tệp kê khai. Tôi ước nó được Android Studio hỗ trợ nhiều hơn, nhưng chỉ chơi xung quanh với các giá trị cho đến khi bạn nhận được đầu ra tên apk mong muốn:

defaultConfig {
        applicationId "com.package.name"
        minSdkVersion 14
        targetSdkVersion 21
        versionCode 6
        versionName "2"
    }
    signingConfigs {
        release {
            keyAlias = "your key name"
        }
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            signingConfig signingConfigs.release
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    output.outputFile = new File(output.outputFile.parent, output.outputFile.name.replace("app-release.apk", "appName_" + versionName + ".apk"))
                }
            }
        }
    }
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.