首页 文章

如何使用gradle在APK文件名中设置versionName?

提问于
浏览
150

我正在尝试在gradle自动生成的APK文件名中设置特定的版本号 .

现在gradle生成 myapp-release.apk 但我希望它看起来像 myapp-release-1.0.apk .

我试过重命名看起来很乱的选项 . 有一个简单的方法吗?

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

我试过上面的代码没有运气 . 有什么建议? (使用gradle 1.6)

14 回答

  • 169

    我只需要在一个地方更改版本名称 . 代码也很简单 .

    下面的示例将创建名为MyCompany-MyAppName-1.4.8-debug.apk或MyCompany-MyAppName-1.4.8-release.apk的apk文件,具体取决于所选的构建变体 .

    另见:How to change the proguard mapping file name in gradle for Android project

    最近Gradle插件的解决方案

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

    上述解决方案已使用以下Android Gradle插件版本进行测试:

    • 3.1.0(2018年3月)

    • 3 . 0 . 1(2017年11月)

    • 3 . 0 . 0(2017年10月)

    • 2 . 3 . 2(2017年5月)

    • 2 . 3 . 1(2017年4月)

    • 2 . 3 . 0(2017年2月)

    • 2 . 2 . 3(2016年12月)

    • 2.2.2

    • 2 . 2 . 0(2016年9月)

    • 2 . 1 . 3(2016年8月)

    • 2.1.2

    • 2 . 0 . 0(2016年4月)

    • 1.5.0(2015/11/12)

    • 1.4.0-beta6(2015/10/05)

    • 1.3.1(2015/08/11)

    随着新版本的推出,我会更新这篇文章 .

    仅在版本1.1.3-1.3.0上测试的解决方案

    以下解决方案已使用以下Android Gradle插件版本进行测试:

    • 1.3.0(2015/07/30) - Not Working, bug scheduled to be fixed in 1.3.1

    • 1.2.3(2015/07/21)

    • 1.2.2(2015/04/28)

    • 1.2.1(2015/04/27)

    • 1.2.0(2015/04/26)

    • 1.2.0-beta1(2015/03/25)

    • 1.1.3(2015/03/06)

    app gradle文件:

    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"
        }
    }
    
  • 1

    这解决了我的问题:使用 applicationVariants.all 而不是 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")) 
            }
        }       
    }
    

    更新:

    所以这似乎不适用于0.14版本的android studio gradle插件 .

    这样做的伎俩(参考此question):

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

    (EDITED to work with Android Studio 3.0 and Gradle 4)

    我正在寻找一个更复杂的apk文件名重命名选项,我写了这个,希望它对任何人都有帮助 . 它使用以下数据重命名apk:

    • flavor

    • build type

    • version

    • date

    它花了我一些关于gradle类的研究和一些其他答案的复制/粘贴 . 我正在使用 gradle 3.1.3 .

    在build.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)
            }
        }
    }
    

    如果您今天(10-10-16)在10:47编译,您将获得以下文件名,具体取决于您选择的风格和构建类型:

    • dev debug :myProject_ dev_debug_1.3.6 _131016_1047.apk

    • dev release :myProject_ dev_release_1.3.6 _131016_1047.apk

    • prod debug :myProject_ prod_debug_1.2.0 _131016_1047.apk

    • prod release :myProject_ prod_release_1.2.0 _131016_1047.apk

    注意:未对齐版本的apk名称仍然是默认名称 .

  • 18

    综上所述,对于那些不知道如何在 build.gradle 中导入包的人(像我一样),请使用以下 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")) 
            }
        }       
    }
    

    =====编辑=====

    如果您在 build.gradle 文件中设置 versionCodeversionName ,如下所示:

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

    你应该这样设置:

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

    ======使用Android Studio 1.0编辑======

    如果您使用的是Android Studio 1.0,则会出现如下错误:

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

    您应该将 build.Types 部分更改为:

    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"))
                    }
                }
            }
        }
    
  • 183

    如果未在defaultConfig块中指定versionName,则 defaultConfig.versionName 将导致 null

    要从manifest中获取versionName,您可以在build.gradle中编写以下代码:

    import com.android.builder.DefaultManifestParser
    
    def manifestParser = new DefaultManifestParser()
    println manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)
    
  • 3

    就我而言,我只想找到一种方法来自动生成 releasedebug 变体的不同 apk 名称 . 通过将此代码段作为 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)
        }
    }
    

    对于新的Android gradle插件3.0.0,您可以执行以下操作:

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

    这产生类似的东西: My_nice_name_3.2.31_dbg.apk

  • 3

    另一种方法是使用以下方法:

    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
    }
    

    这将为您的所有apk输出设置“appname-1.0.0” .

  • 7

    Gradle 4

    语法在Gradle 4(Android Studio 3)中有所改变(从 output.outputFileoutputFileName ,想法来自this answer现在:

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

    有许多答案在完整或经过一些修改后都是正确的 . 但是我还是会添加我的,因为我遇到了所有问题,因为我使用脚本通过挂钩到 preBuild 任务来动态生成VersionName和VersionCode .

    如果您使用的是类似的方法,那么这将是可行的代码:

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

    解释:因为我在 preBuild 的第一个操作中覆盖了版本代码和名称,所以我必须将文件重命名添加到此任务的末尾 . 那么gradle在这种情况下会做的是:

    注入版本代码/名称 - >执行preBuild操作 - >替换apk的名称

  • 5

    按照@Jon answer重命名apk的正确方法

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

    或者用另一种方法可以获得相同的结果

    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"
            }
        }
    }
    
  • 0
    applicationVariants.all { variant ->
            variant.outputs.all { output ->
                output.outputFileName = output.outputFileName.replace(".apk", "-${variant.versionName}.apk")
            }
        }
    
  • 2

    在我的情况下,我这样解决这个错误

    在调试版本中添加SUFFIX,在这种情况下,我将“-DEBUG”文本添加到我的Debug部署中

    buildTypes {
            release {
    
                signingConfig signingConfigs.release
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    
    
            }
            debug {
    
                defaultConfig {
                    debuggable true
    
                    versionNameSuffix "-DEBUG"
                }
            }
        }
    
  • 5

    最新消息您可以使用以下代码段的gradle版本:

    首先设置应用程序清单位置

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

    后来在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"))
        }
    }
    

    如果每种构建类型有不同的清单,请进行调整 . 但既然我有单一的 - 对我来说很完美 .

  • 17

    从Android Studio 1.1.0开始,我发现这个组合在 build.gradle 文件的 android 主体中有效 . 这是因为您无法弄清楚如何导入清单xml文件数据 . 我希望它能得到Android Studio的更多支持,但只需使用这些值,直到获得所需的apk名称输出:

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

相关问题