如何自定义产品风味的 APK 文件名?

Posted

技术标签:

【中文标题】如何自定义产品风味的 APK 文件名?【英文标题】:How to customize the APK file name for product flavors? 【发布时间】:2014-09-26 01:54:15 【问题描述】:

我正在 build.gradle 脚本中自定义我的 android 应用程序的 APK 文件名,如下所示:

android 
    defaultConfig 
        project.ext.set("archivesBaseName", "MyApplication");
    

现在我正在使用产品风味:

android 
    productFlavors 
        green 
            applicationId "com.example.myapplication.green"
        

        blue 
            applicationId "com.example.myapplication.blue"
        
    

有没有办法自定义每个 APK 的名称?我尝试了archiveBaseNamebaseName,但没有成功。最后我想提出以下文件:

build/outputs/apk/Blue-debug-1.2.1.apk
build/outputs/apk/Blue-debug-unaligned.apk
build/outputs/apk/Blue-release-1.2.1.apk
build/outputs/apk/Blue-release-unaligned.apk
build/outputs/apk/Green-debug-1.2.1.apk
build/outputs/apk/Green-debug-unaligned.apk
build/outputs/apk/Green-release-1.2.1.apk
build/outputs/apk/Green-release-unaligned.apk

【问题讨论】:

【参考方案1】:

这将在 2021 年帮助您。

android 
    
//........
flavorDimensions "version"
productFlavors 
    Free 
        dimension "version"
        applicationId "com.exampleFree.app"
    
    Paid 
        dimension "version"
        applicationId "com.examplePaid.app"
    


applicationVariants.all  variant ->
    variant.outputs.all  output ->
        def appId = variant.applicationId// com.exampleFree.app OR com.examplePaid.app
        def versionName = variant.versionName
        def versionCode = variant.versionCode // e.g 1.0
        def flavorName = variant.flavorName // e. g. Free
        def buildType = variant.buildType.name // e. g. debug
        def variantName = variant.name // e. g. FreeDebug

        //customize your app name by using variables
        outputFileName = "$variantName.apk"
    

Apk 名称 FreeDebug.apk

证明

【讨论】:

不适合我,它什么也没做。我添加了一个“println outputFileName”,它打印正确,但由于某种原因,gradle 没有使用文件名的“outputFileName”值。顺便说一句,我正在尝试将它用于 app bundle,而不是 APK。 在 2021 年使用 Bundles 时不起作用。 与 APK 完美搭配。【参考方案2】:

这里的每个答案都是一样的,而且已经过时了。很容易做到[风味]-[版本]-[构建类型]:

android 
    productFlavors 
        green 
            applicationId "com.example.myapplication.green"
            setProperty("archivesBaseName", "Green-" + defaultConfig.versionName)
        

        blue 
            applicationId "com.example.myapplication.blue"
            setProperty("archivesBaseName", "Blue-" + defaultConfig.versionName)
        
    

如果你的 versionName 是“1.2.1”,运行 gradle assemble 会产生:

Green-1.2.1-debug.apk

Green-1.2.1-release.apk

Blue-1.2.1-debug-apk

Blue-1.2.1-release.apk

【讨论】:

【参考方案3】:

这是你需要的

android 
    defaultConfig 
        ……

        // custom output apk name
        applicationVariants.all  variant ->
            variant.outputs.all 
                outputFileName = "$variant.productFlavors[0].name-$variant.buildType.name-$variant.versionName.apk"
            
        
    
    ……

【讨论】:

【参考方案4】:

对于 Android Studio 3.0,您必须更改:

applicationVariants.all  variant ->
    variant.outputs.each  output ->
        output.outputFile = new File(output.outputFile.parent, "whatever" + ".apk")
    

收件人:

android.applicationVariants.all  variant ->
        variant.outputs.all  
            outputFileName = "whatever" + ".apk")
    

【讨论】:

【参考方案5】:

试着把它放在你的 build.gradle 的 android 闭包中

buildTypes 
    debug 
        // debug buildType specific stuff
    
    release 
        // release buildType specific stuff
    
    applicationVariants.all  variant ->
        if (variant.buildType.name.equals("release") &&
            variant.productFlavors[0].name.equals("green") &&
            variant.zipAlign) 
                def apk = variant.outputFile;
                variant.outputFile = new File(apk.parentFile, "green.apk");
         else if(variant.buildType.name.equals("release") &&
            variant.productFlavors[0].name.equals("blue") &&
            variant.zipAlign) 
                def apk = variant.outputFile;
                variant.outputFile = new File(apk.parentFile, "blue.apk");
        
    

现在输出应该类似于green.apkblue.apk

【讨论】:

如果你对“freeflavor”和“proflavor”都做同样的事情,为什么还要检查产品风味名称?我真正想要的是像您的示例中那样更改“模块名称”-不附加任何内容。 仍然:我之前问过你有两个 if 块的原因是什么? 是的。它在这里没有多大用处,可以进一步简化。 if 语句圆括号不完整......虽然即使把它们放在那里对我也没有影响 这不起作用,缺少paren并且显然与Android插件不兼容?我收到有关未定义属性 outputFile 的错误。请参阅下面的答案,其中显示了我是如何修复它的。【参考方案6】:

这是我上面 Lakshman 答案的变体(呵呵),不知道为什么我需要“variants.outputs.each”,但我确实需要。

defaultConfig 
    applicationId "my.company.com"
    minSdkVersion 16
    targetSdkVersion 25
    applicationVariants.all  variant ->
        if (variant.productFlavors[0].name.equals("VariantA")) 
            variant.outputs.each  output ->
                def apk = output.outputFile;
                output.outputFile = new File(apk.parentFile, "Blue.apk");
            
         else  // Only two variants
            variant.outputs.each  output ->
                def apk = output.outputFile;
                output.outputFile = new File(apk.parentFile, "Green.apk");
            
        
    

【讨论】:

【参考方案7】:

这对我有用:

在 APK 名称中添加 variant.productFlavors[0].name

代码示例:

buildTypes 
    release 
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        applicationVariants.all  variant ->
            variant.outputs.each  output ->
                output.outputFile = new File(output.outputFile.parent, "APPNAME_" + variant.productFlavors[0].name + "_" + variant.versionName + ".apk")

            
        
    

【讨论】:

【参考方案8】:

我正在使用以下内容,因此文件不会相互覆盖:

applicationVariants.all  variant ->
    variant.outputs.each  output ->
        def newApkName = variant.name + "-" + variant.versionName + "(" + variant.versionCode +")" + ".apk";
        output.outputFile = new File("$project.projectDir/outputs/apk/" + variant.name, newApkName);
    

【讨论】:

【参考方案9】:

我是这样做的:

productFlavors 
        production 
            applicationId "com.example.production"
        

        staging 
            applicationId "com.example.production.staging"

        

        applicationVariants.all  variant ->
            variant.outputs.each  output ->
                if(variant.productFlavors[0].name.equals("staging"))
                    output.outputFile = new File(output.outputFile.parent,
                            output.outputFile.name.replace("app-staging-release",  "test"));

                else
                    output.outputFile = new File(output.outputFile.parent,
                            output.outputFile.name.replace("app-production-release",  "production"));
                

            
        
    

【讨论】:

什么是outputFile??【参考方案10】:

对于 Android Gradle 插件 0.13.+,您应该使用如下内容:

android
    buildTypes 
        applicationVariants.all  variant ->
            variant.outputs.each  output ->
                def apk = output.outputFile;
                def newName = "mysms-" + variant.baseName.replace("-release", "") + "-" + defaultConfig.versionName + ".apk";
                output.outputFile = new File(apk.parentFile, newName);
            
        
    

【讨论】:

这已在 Android Gradle 3.0.0-alpha1 中停止工作。您似乎无法再访问 outputFile。 如果你不想更新你的 gradle 版本真的很有用!【参考方案11】:

Android Gradle Plugin 0.13.0 已弃用以下中使用的 outputFile:

applicationVariants.all  variant ->
    def newApkName = variant.name + "my-custom-addition" + ".apk";
    variant.outputFile = new File("$project.buildDir/outputs/apk/", newApkName);

对我有用的解决方案是:

android 
... 


project.archivesBaseName = "AndroidAppGeneric-$_buildVersionNameForMaven"

【讨论】:

【参考方案12】:

你需要这个很奇怪,因为默认情况下,apk 文件名已经不同了。

如果您查看第 1346 行的 here,您可以看到在 outputFile 中使用了 variantData.variantConfiguration.baseName。

variantData.outputFile = project.file("$project.buildDir/apk/$project.archivesBaseName-$variantData.variantConfiguration.baseName.apk")

baseName 的文档是

/**
 * Full, unique name of the variant, including BuildType, flavors and test, dash separated.
 * (similar to full name but with dashes)
 */
private String mBaseName;

所以运行gradle assembleFreeDebug 应该会得到一个ProjectName-free-debug.apk 文件。

但如果不是这样,或者你想要一个不同的文件名,你可以使用下面的代码来自定义它。

android 
    buildTypes 
        debug 
        alpha 
        release 
    
    productFlavors 
        free
        paid
    
    applicationVariants.all  variant ->
        def newApkName = variant.name + "my-custom-addition" + ".apk";
        variant.outputFile = new File("$project.buildDir/outputs/apk/", newApkName);
    

【讨论】:

快到了。 (1) 出于某种原因,build/outputs/apk 中的 -unaligned.apk 文件仍带有 MyApplication 前缀。 (2) 变体不大写。 知道如何完成这个吗? (1) 根据 BasePlugin.groovy-link 中的第 1316 行,您可以更改 project.archivesBaseNamevariantData.variantConfiguration.baseName 以适应 unaligned-outputname。但我注意到这是否会与其他构建步骤混淆。不过,您不应该使用未对齐的版本,而应该使用最终的 apk(您可以完全控制其中的 apk 名称)。 (2) variant.name.capitalize()

以上是关于如何自定义产品风味的 APK 文件名?的主要内容,如果未能解决你的问题,请参考以下文章

android打包生成apk时自定义文件名版本号。自定义项目字段等等

Gradle实现自动打包,签名,自定义apk文件名

Android 在 APK 中保存自定义数据

Android studio 自定义打包apk名

Android studio 自定义打包APK名称

如何显示 WooCommerce 产品的自定义分类?