如何使用 gradle 在 APK 文件名中设置 versionName?
Posted
技术标签:
【中文标题】如何使用 gradle 在 APK 文件名中设置 versionName?【英文标题】:How to set versionName in APK filename using gradle? 【发布时间】:2013-08-22 08:27:05 【问题描述】:我正在尝试在 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)
【问题讨论】:
【参考方案1】:我只需在一处更改版本名称。代码也很简单。
以下示例将创建名为 MyCompany-MyAppName-1.4.8-debug.apk 或 MyCompany-MyAppName-1.4.8-release.apk 的 apk 文件,具体取决于在所选的构建变体上。
请注意,此解决方案适用于 APK 和 App Bundles (.aab files)。
另请参阅: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.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 仅在 1.1.3-1.3.0 版本上测试 以下解决方案已使用以下 Android Gradle 插件版本进行测试:
1.3.0 (2015/07/30) - 不工作,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)应用 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"
【讨论】:
我认为这是正确的方法,而不是编写另一个任务来重命名文件。 如果你有强迫症并且不希望 AS 警告你 +,只需更改为 archivesBaseName = "MyCompany-MyAppName-$versionName" 很棒的发现,但不适用于具有不同版本代码的风味。它们都以相同的版本代码结束。 有什么办法可以在名字后面加上variant.buildType.name
?我知道这实际上与默认配置无关,但我正在尝试弄清楚如何删除过时的 variantOutput.getAssemble()
警告
是否可以从 apk 名称中删除最后一个 '-debug' / '-release'?【参考方案2】:
这解决了我的问题:使用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"))
【讨论】:
如果我在AndroidManifest.xml
中定义了versionName
而不是gradle 配置,你知道如何让它工作吗?它现在给我myapp-release-null.apk
。
此答案不适用于 0.14+ 版本的 gradle 插件。有任何更新可以使用这些吗?
@withoutclass 我问了这个问题并在这里得到了回答:***.com/questions/27068505/…
对于更新到 Gradle 4 的用户:将 each
更改为 all
并将 output.outputFile
更改为 outputFileName
。如果有人确认这是可行的,则可以将其编辑为答案:)
@phpirate:几乎可以工作:Error:(34, 0) Cannot set the value of read-only property 'name'
【参考方案3】:
(经过编辑以使用 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)
如果您今天(2016 年 13 月 10 日)10:47 进行编译,您将获得以下文件名,具体取决于您选择的风格和构建类型:
开发调试:myProject_dev_debug_1.3.6_131016_1047.apk 开发版本:myProject_dev_release_1.3.6_131016_1047.apk prod 调试:myProject_prod_debug_1.2.0_131016_1047.apk 产品发布:myProject_prod_release_1.2.0_131016_1047.apk注意:未对齐的版本apk名称仍然是默认的。
【讨论】:
很好的解决方案。我试过了,它非常适合我的问题。谢谢! 是否可以在 Xamarin Studio 中使用相同的方法? 如果可能的话,那就太好了,但我现在开始学习 Xamarin 课程,但我仍然没有足够的练习来知道它是否可能。我会问这个问题,然后再来这里。 课程老师的评论:“有一个选项,您可以使用命令来更改生成文件的名称”。因此,从 Xamarin 中使用的方法必须与我为 Android Studio 编写的方法不同,抱歉。 解决错误无法设置只读属性'outputFile'的值 - 正如前面评论中提到的,必须“将each
更改为all
和 output.outputFile
到 outputFileName
" - 这篇文章提供了一些细节:***.com/a/44265374/2162226【参考方案4】:
总结一下,对于那些不知道如何在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
文件中设置versionCode
和versionName
,如下所示:
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"))
【讨论】:
这很好用。但是,由于我在 gradle 构建中增加了清单版本,它将创建一个具有较旧(预增量)值的 APK。有什么方法可以确保在 gradle 脚本增加版本号后生效? @Guy 抱歉拖了这么久。我编辑了答案,看看能不能解决你的问题。【参考方案5】:如果您未在 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)
【讨论】:
相信随着gradle以后的版本,现在是com.android.builder.core.DefaultManifestParser【参考方案6】:就我而言,我只是想找到一种方法来自动为release
和debug
变体生成不同的apk
名称。我通过将这个 sn-p 作为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
【讨论】:
【参考方案7】: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.outputFile
到 outputFileName
,this answer 的想法现在是:
android
applicationVariants.all variant ->
variant.outputs.each output ->
def newName = outputFileName
newName.replace(".apk", "-$variant.versionName.apk")
outputFileName = new File(newName)
【讨论】:
知道如何为 gradle 6 解决这个问题吗?【参考方案8】:另一种选择是使用以下内容:
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”。
【讨论】:
对不起不起作用(不再):No such property: archivesBaseName for class: org.gradle.api.internal.project.DefaultProject_Decorated
你用的是什么gradle版本?【参考方案9】:
按照@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"
【讨论】:
这个不错!我更喜欢这种方式,而不是我目前这样做的其他方式。【参考方案10】:有很多答案是正确的,无论是完整的还是经过一些修改的。但是我还是要添加我的,因为我遇到了所有问题,因为我使用脚本通过挂钩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 的名称
【讨论】:
你在哪里设置生成的versionCode和versionName变量? 我记得那是在我们的自定义 gradle 插件中完成的。它的执行被称为 preBuild 任务的最后一个动作。【参考方案11】: applicationVariants.all variant ->
variant.outputs.all output ->
output.outputFileName = output.outputFileName.replace(".apk", "-$variant.versionName.apk")
【讨论】:
虽然这段代码 sn-p 可以解决问题,including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。【参考方案12】:就我而言,我通过这种方式解决了这个错误
在 Debug 版本中添加 SUFFIX,在这种情况下,我将“-DEBUG”文本添加到我的 Debug 部署中
buildTypes
release
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
debug
defaultConfig
debuggable true
versionNameSuffix "-DEBUG"
【讨论】:
这不会更改 APK 文件名。 事实上,这是一个不错的提示。不是在正确的问题,但很好。我在哪里可以阅读更多关于它的信息?是否可以基于 GIT 分支使用versionNameSuffix
?例如,如果它不在“master”上,则始终有一个后缀,即使它是发布版本【参考方案13】:
对于最新的 gradle 版本,您可以使用以下 sn-p:
首先设置您的应用程序清单位置
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"))
如果每种构建类型有不同的清单,请进行调整。但因为我只有一个 - 非常适合我。
【讨论】:
是否可以将类文件中的字符串添加到 apk 名称中??【参考方案14】:从 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"))
【讨论】:
【参考方案15】:正如我回答的here 如果您想将版本名称和版本代码附加到输出文件中,请执行以下操作:
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'
【讨论】:
【参考方案16】:您还可以在 apk 名称中添加格式化的构建时间,如下所示:
setProperty("archivesBaseName", "data-$versionName " + (new Date().format("HH-mm-ss")))
【讨论】:
以上是关于如何使用 gradle 在 APK 文件名中设置 versionName?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 build.gradle 文件中设置属性以在 Java 中访问该属性
如何使用 JAVA_OPTS 在 gitlab-ci.yaml 中设置 Gradle 代理变量
如何在 build.gradle.kts 中设置 openApi 生成器全局属性