如何更改默认生成的apk名称"app-release.apk"

210
无论何时我在Android Studio中生成已签名的apk,默认情况下它会将名称赋为app-release.apk...
我们可以进行任何设置,以便它应该提示并询问我要分配给apk的名称(它在eclipse中所做的方式)吗?
我的做法是-在生成后重新命名apk。这不会产生任何错误,但是否有任何真正的方法,使我可以在设置中进行任何更改以获得提示。
注意:
在生成apk时,Android Studio会给我一个提示选择位置(仅限) enter image description here

  1. 将构建变量更改为发布版本。
  2. 从菜单栏中选择“构建”->“生成已签名的APK”来生成已签名的APK。
- Prabs
这里的所有答案都不正确。使用它们中的任何一个仍然会出现此问题... 问题在于Studio缓存了apk构件的名称,并继续使用缓存的名称而不是使用新生成的名称! - TacB0sS
20个回答

162
是的,我们可以改变那个问题,但需要更多关注。

SeeThis

现在在您的项目中的 build.gradle 添加此内容,同时确保您已经检查了您的项目的 build variant,例如 release 或 Debug。这里我将我的构建变量设置为 release,但您也可以选择 Debug。
    buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                signingConfig getSigningConfig()
                applicationVariants.all { variant ->
                    variant.outputs.each { output ->
                        def date = new Date();
                        def formattedDate = date.format('yyyyMMddHHmmss')
                        output.outputFile = new File(output.outputFile.parent,
                                output.outputFile.name.replace("-release", "-" + formattedDate)
    //for Debug use output.outputFile = new File(output.outputFile.parent,
   //                             output.outputFile.name.replace("-debug", "-" + formattedDate)
                        )
                    }
                }
            }
        }

你可以用不同的方法来做,就像这样。
 defaultConfig {
        applicationId "com.myapp.status"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        setProperty("archivesBaseName", "COMU-$versionName")
    }

在build.gradle文件中使用Set属性方法 在运行项目之前不要忘记同步gradle 希望这能解决您的问题 :)

Google最近推出了一种处理方法 现在,您可以根据flavor或Variant输出重命名构建 //以下来源于开发者Android文档 有关详细信息,请遵循上面的文档链接
使用Variant API操作变体输出与新插件不兼容。对于简单的任务仍然有效,例如在构建时更改APK名称,如下所示:

// If you use each() to iterate through the variant objects,
// you need to start using all(). That's because each() iterates
// through only the objects that already exist during configuration time—
// but those object don't exist at configuration time with the new model.
// However, all() adapts to the new model by picking up object as they are
// added during execution.
android.applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = "${variant.name}-${variant.versionName}.apk"
    }
}

更改 .aab 包的名称 David Medenjak 在这里给出了很好的回答。
tasks.whenTaskAdded { task ->
    if (task.name.startsWith("bundle")) {
        def renameTaskName = "rename${task.name.capitalize()}Aab"
        def flavor = task.name.substring("bundle".length()).uncapitalize()
        tasks.create(renameTaskName, Copy) {
            def path = "${buildDir}/outputs/bundle/${flavor}/"
            from(path)
            include "app.aab"
            destinationDir file("${buildDir}/outputs/renamedBundle/")
            rename "app.aab", "${flavor}.aab"
        }

        task.finalizedBy(renameTaskName)
    }
//@credit to David Medenjak for this block of code
}

需要上述代码吗?

我在最新版本的Android Studio 3.3.1中观察到以下内容

之前的代码已经完成了.aab捆绑包的重命名,不需要任何重命名任务。

希望这能帮助大家。 :)


@AbhishekChaubey 我也遇到了同样的问题。就像你说的那样,我清理了代码,删除了构建文件夹,重新启动了工作室。但仍然没有得到解决。 - Nigam Patro
@NigamPatro,您在应用上述解决方案后是否有任何日志记录?请详细说明您的问题。 - Abhishek Chaubey
5
从Android Studio 3.0开始,output.outputFile是只读的。@johnny-doe的答案是新的解决方案。 - krishh
我们如何将架构名称添加到apk名称中?例如“MyApp_V223_151118_R_arm.apk”和“MyApp_V223_151118_R_x86.apk”。 - b24
有人知道如何设置应用程序包名称,以类似的方式呈现,即使按照上述步骤操作后仍然默认为app.aab。 - shaby
显示剩余12条评论

97

如果您使用了最新的Android Gradle插件(3.0),可能会遇到以下错误:

无法设置只读属性“outputFile”的值

根据迁移指南,我们现在应该采用以下方法:

applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = "${applicationName}_${variant.buildType.name}_${defaultConfig.versionName}.apk"
    }
}

注意这里的两个主要更改:

  1. all 现在用于迭代变量输出,而不是使用 each
  2. 使用 outputFileName 属性,而非改变文件引用。

1
现在这是2017年10月Android Studio 3.0 Beta 7的正确答案。谢谢。 - krishh
7
在我的情况下,${applicationName}解析为BuildType_Decorated{name=applicationName, debuggable=false, testCoverageEnabled=false, jniDebuggable=false, pseudoLocalesEnabled=false, renderscript...(为了清晰简明而缩写)。这导致打包失败。对我来说${applicationId}${archivesBaseName}是更好的选择。另外,${defaultConfig.versionName}在我的情况下为null。因此,我最终选择${applicationId}_${variant.name}-${variant.versionName} - pcdev
在同步(Gradle v4.4)时出现了“Gradle Messages”中的错误:“No signature of method: java.util.ArrayList.all() is applicable for argument types: (build_8pov2vcee3orzmdxelrhjbbwu$_run_closure2$_closure6$_closure12$_closure13) values: [build_8pov2vcee3orzmdxelrhjbbwu$_run_closure2$_closure6$_closure12$_closure13@296351f6] Possible solutions: tail(), any(), tail(), last(), last(), add(java.lang.Object)” 我将其添加到defaultConfig{}块和buildTypes {release{}}块中,都出现了相同的错误。目前还不确定如何解决此问题。 - CybeX
1
通常情况下,@KGCybeX 这段代码是在与 defaultConfig{} 同级别的 android{} 部分中使用的。但是,你也可以使用 android.applicationVariants.all { } 语法将其用于 android{} 之外。 - Johnny Doe
@JohnnyDoe 謝謝你的幫助,我剛按照你建議的做了,但沒有成功。我將代碼添加到android{}塊的末尾,但仍然出現上面提到的錯誤 ->Gradle在底部顯示錯誤信息 https://pastebin.com/Kk2JwPGA - CybeX
1
使用Gradle 5.1.1进行工作。 - Williaan Lopes

67

这里有一个更简短的方法:

defaultConfig {
    ...
    applicationId "com.blahblah.example"
    versionCode 1
    versionName "1.0"
    setProperty("archivesBaseName", applicationId + "-v" + versionCode + "(" + versionName + ")")
    //or so
    archivesBaseName = "$applicationId-v$versionCode($versionName)"
}

它会给你一个名为com.blahblah.example-v1(1.0)-debug.apk(在调试模式下)的文件。

Android Studio默认按构建类型名称添加versionNameSuffix,如果您想覆盖此选项,请按以下步骤操作:

buildTypes {
    debug {
        ...
        versionNameSuffix "-MyNiceDebugModeName"
    }
    release {
        ...
    }
}

调试模式下的输出:com.blahblah.example-v1(1.0)-MyNiceDebugModeName.apk


5
谢谢。这是最快的选择! - John
2
顺便提一下,您可以将archiveBaseName添加到本地gradle.properties文件中。 - Ge3ng
这似乎更清晰明了。为什么这不是首选解决方案? - Xan-Kun Clark-Davis
1
有什么办法可以去掉“-debug”后缀吗? - Roshana Pitigala
2
这会影响应用程序的版本名称,而不是文件名:https://dev59.com/Rp7ha4cB1Zd3GeqPgDpm#41665729 - Daniel Wilson
显示剩余2条评论

55

(已编辑以适用于Android Studio 3.0和Gradle 4)

我正在寻找更复杂的APK文件名重命名选项,并编写了以下解决方案,可将APK重命名为以下数据:

  • flavor
  • build type
  • version
  • date

您会得到这样的apk:myProject_dev_debug_1.3.6_131016_1047.apk

您可以在此处找到完整的答案。希望能有所帮助!

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

2
很好。唯一需要改进的是为某些风味或构建类型(flavor ==“dev”|| buildType =“debug”)提供一个恒定的文件名(无版本或日期)。 - Tony BenBrahim
这里似乎很重要的是“全部”而不是“每个”。 - Xan-Kun Clark-Davis
出现错误 > groovy.lang.MissingPropertyException: No such property: variantConfiguration for class: com.android.build.gradle.internal.variant.ApplicationVariantData。为什么不直接改成 buildType = variant.buildType.name - soshial
“file.apk” 不可写 - Hosein Haqiqian
你知道这行代码 "variant.productFlavors[0]" 的作用吗?它不会返回实际构建的产品口味,而是 gradle 文件中出现的第一个口味。 - Farid
对于Android Studio 4,应该使用以下代码: def buildType = variant.buildType.name 而不是 def buildType = variant.variantData.variantConfiguration.buildType.name - Volodymyr

53

我修改了@Abhishek Chaubey的答案,以更改整个文件名:

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                project.ext { appName = 'MyAppName' }
                def formattedDate = new Date().format('yyyyMMddHHmmss')
                def newName = output.outputFile.name
                newName = newName.replace("app-", "$project.ext.appName-") //"MyAppName" -> I set my app variables in the root project
                newName = newName.replace("-release", "-release" + formattedDate)
                //noinspection GroovyAssignabilityCheck
                output.outputFile = new File(output.outputFile.parent, newName)
            }
        }
    }
    debug {
    }
}

这将生成一个文件名,如:MyAppName-release20150519121617.apk


3
如何在Gradle中添加变量: - Mehdiway
1
为了添加自定义的“appName”属性,请将以下代码添加到您的根项目中: project.ext { appName = 'MyApplicatioName' } - miha
2
@ranma2913,我在更改apk名称后无法通过Android Studio运行代码,有什么想法吗?请帮忙...它显示:磁盘上不存在APK文件 /Users/.../outputs/apk/NewName-debug-20161004172815.apk。 - Beeing Jk
2
不需要手动设置 MyAppName,使用 rootProject.name 就可以获取项目名称,就像在 Eclipse 中一样。 - Hiren Dabhi
3
从Android Studio 3.0开始,output.outputFile是只读的。@johnny-doe的答案是新的解决方案。 - krishh
显示剩余2条评论

8

我根据@Fer的答案编写了更通用的解决方案。

它还应该可以处理基于flavor和构建类型的applicationIdversionNameversionCode配置。

在build.gradle中:

android {
    ...
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def appId = variant.applicationId
            def versionName = variant.versionName
            def versionCode = variant.versionCode
            def flavorName = variant.flavorName // e. g. free
            def buildType = variant.buildType // e. g. debug
            def variantName = variant.name // e. g. freeDebug

            def apkName = appId + '_' + variantName + '_' + versionName + '_' + versionCode + '.apk';
            output.outputFile = new File(output.outputFile.parentFile, apkName)
        }
    }
}

示例apk名称:com.example.app_freeDebug_1.0_1.apk

有关variant变量的更多信息,请参见ApkVariantBaseVariant接口定义。


6

在您的应用级 Gradle 文件中添加以下类似于 android.applicationVariants.all 的代码块

buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            lintOptions {
                disable 'MissingTranslation'
            }
            signingConfig signingConfigs.release
            android.applicationVariants.all { variant ->
                variant.outputs.all {
                    outputFileName = "${applicationId}_${versionCode}_${variant.flavorName}_${variant.buildType.name}.apk"
                }
            }
        }
        debug {
            applicationIdSuffix '.debug'
            versionNameSuffix '_debug'
        }
    }

2019/03/25 可用。


4
使用flavor和split APK对于APK文件而言是如何工作的,而不是适用于Bundle / AAB文件
android {
    ....

    productFlavors {
        aFlavor {
            applicationId "com.a"
        
            versionCode 5
            versionName "1.0.5"

            signingConfig signingConfigs.signingA
        }
        bFlavor {
            applicationId "com.b"

            versionCode 5
            versionName "1.0.5"

            signingConfig signingConfigs.signingB
        }
        cFlavor {
            applicationId "com.c"

            versionCode 3
            versionName "1.0.3"

            signingConfig signingConfigs.signingC
        }
    }

    splits {
        abi {
            enable true
            reset()
            include 'arm64-v8a', 'x86', 'x86_64'
            universalApk false
        }
    }

    android.applicationVariants.all { variant ->
        variant.outputs.all { output ->
            // New one or Updated one
            output.outputFileName = "${variant.getFlavorName()}-${variant.buildType.name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}-${output.getFilter(com.android.build.OutputFile.ABI)}.apk"
            // Old one
            // output.outputFileName = "${variant.buildType.name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}.apk"
        }
    }
}

结果

aFlavor的版本

  • 发布版

    aFlavor-release-v5_1.0.5-16Jan2020_21-26-arm64-v8a.apk

    aFlavor-release-v5_1.0.5-16Jan2020_21-26-x86_64.apk

    aFlavor-release-v5_1.0.5-16Jan2020_21-26-x86.apk

  • 调试版

    aFlavor-debug-v5_1.0.5-16Jan2020_21-26-arm64-v8a.apk

    aFlavor-debug-v5_1.0.5-16Jan2020_21-26-x86_64.apk

    aFlavor-debug-v5_1.0.5-16Jan2020_21-26-x86.apk

bFlavor的版本

名称类似上面的版本,只是将前缀aFlavor替换为bFlavor,例如

  • bFlavor-release-v5_1.0.5-16Jan2020_21-26-arm64-v8a.apk

cFlavor的版本

名称类似上面的版本,只是将前缀aFlavor替换为cFlavor, 并分别更改versionCodeversionName

  • cFlavor-release-v3_1.0.3-16Jan2020_21-26-arm64-v8a.apk

如需了解更多详细信息,请查看此问答线程。


4

针对较新版本的Android Studio Gradle

AppName是您想要的应用程序名称,因此请进行替换。
variantName将是默认选择的变体或风味。
Date will Today's date,所以不需要做任何更改,只需粘贴即可。

applicationVariants.all { variant ->
    variant.outputs.all {
        def variantName = variant.name
        def versionName = variant.versionName
        def formattedDate = new Date().format('dd-MM-YYYY')
        outputFileName = "AppName_${variantName}_D_${formattedDate}_V_${versionName}.apk"
    }
}

Output:

AppName_release_D_26-04-2021_V_1.2.apk

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接