183

我正在尝试在 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)

4

16 回答 16

244

我只需在一处更改版本名称。代码也很简单。

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

请注意,此解决方案适用于 APK 和App Bundle(.aab 文件)

另请参阅:如何在 gradle for Android 项目中更改 proguard 映射文件名

#最近的 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.6.4(2020年8月)
  • 3.5.2(2019 年 11 月)
  • 3.3.0(2019 年 1 月)
  • 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)

当新版本出来时,我会更新这篇文章。

#Solution Tested Only on version 1.1.3-1.3.0 以下解决方案已使用以下 Android Gradle 插件版本进行测试:

  • 1.3.0 (2015/07/30) -不工作,错误计划在 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)

应用程序 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"
    }
}
于 2015-03-11T17:02:52.233 回答
175

这解决了我的问题:使用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 插件。

这可以解决问题(来自此问题的参考 ):

android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.outputFile = new File(
                    output.outputFile.parent,
                    output.outputFile.name.replace(".apk", "-${variant.versionName}.apk"))
        }
    }
}
于 2013-08-20T12:09:25.267 回答
49

(经过编辑以使用 Android Studio 3.0 和 Gradle 4)

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

  • 味道
  • 构建类型
  • 版本
  • 日期

我在 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)
        }
    }
}

如果您今天(13-10-2016)在 10:47 编译,您会根据您选择的风格和构建类型获得以下文件名:

  • 开发调试:myProject_dev_debug_1.3.6 _131016_1047.apk
  • 开发版本:myProject_dev_release_1.3.6 _131016_1047.apk
  • 产品调试:myProject_ prod_debug_1.2.0 _131016_1047.apk
  • 产品发布:myProject_ prod_release_1.2.0 _131016_1047.apk

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

于 2016-10-13T09:14:48.357 回答
19

总结一下,对于那些不知道如何导入包的人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")) 
        }
    }       
}

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

如果您像这样在文件中设置versionCode和:versionNamebuild.gradle

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"))
                }
            }
        }
    }
于 2014-07-09T09:18:01.973 回答
17

如果您没有在 defaultConfig 块中指定 versionName,那么defaultConfig.versionName将导致null

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

import com.android.builder.DefaultManifestParser

def manifestParser = new DefaultManifestParser()
println manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)
于 2013-10-16T14:28:18.580 回答
8

就我而言,我只是想找到一种方法来自动生成不同的apk名称releasedebug变体。我设法通过将此代码段作为子项轻松地做到这一点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

于 2017-04-18T13:38:30.867 回答
8

摇篮 6+

我现在在 Android Studio 4.0 和 Gradle 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"
                }
            }
        }
    }
}

摇篮 4

Gradle 4(Android Studio 3+)中的语法发生了一些变化(从output.outputFileto ,这个答案outputFileName的想法现在是:

android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def newName = outputFileName
            newName.replace(".apk", "-${variant.versionName}.apk")
            outputFileName = new File(newName)
        }
    }
}
于 2017-12-10T16:36:18.290 回答
7

另一种选择是使用以下内容:

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”。

于 2014-12-12T17:06:53.567 回答
5

根据@Jon的回答,重命名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"
        }
    }
}
于 2018-09-05T07:22:48.427 回答
3

有很多答案是完全正确的,或者经过一些修改后是正确的。但无论如何我都会添加我的,因为我遇到了所有问题,因为我使用脚本通过挂钩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 会做的是:

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

于 2015-09-01T09:31:54.120 回答
2
    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            output.outputFileName = output.outputFileName.replace(".apk", "-${variant.versionName}.apk")
        }
    }
于 2018-02-17T19:14:28.387 回答
1

就我而言,我以这种方式解决了这个错误

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

 buildTypes {
        release {

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


        }
        debug {

            defaultConfig {
                debuggable true

                versionNameSuffix "-DEBUG"
            }
        }
    }
于 2016-02-05T12:10:44.900 回答
0

对于最新的 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"))
    }
}

如果每种构建类型有不同的清单,请进行调整。但因为我有一个 - 非常适合我。

于 2015-02-22T03:35:12.613 回答
0

从 Android Studio 1.1.0 开始,我发现这种组合在文件的android正文中有效build.gradle。这是如果您不知道如何导入清单 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"))
                }
            }
        }
    }
于 2015-05-20T20:31:40.230 回答
0

正如我在这里回答的那样如果您想将版本名称和版本代码附加到输出文件中,请执行以下操作:

applicationVariants.all { variant ->
        variant.outputs.all {
            def versionName = variant.versionName
            def versionCode = variant.versionCode
            def variantName = variant.name
            outputFileName = "${rootProject.name}" + '_' + variantName + '_' + versionName + '_' + versionCode + '.apk'
        }
    }
于 2020-11-05T05:39:12.897 回答
0

您还可以将格式化的构建时间添加到 apk 名称,如下所示:

setProperty("archivesBaseName", "data-$versionName " + (new Date().format("HH-mm-ss")))
于 2021-03-26T12:59:40.710 回答