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

52

我正在通过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
12个回答

28

请尝试将此代码添加到您的 build.gradle 文件中:

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”都做同样的事情呢?我真正想要的是像你的例子一样改变“模块名称”,而不是附加一些东西。 - JJD
仍然有一个问题:就像我之前问过的那样,你为什么要有两个if块呢? - JJD
是的。它在这里没有什么作用,可以进一步简化。 - Lakshman Chilukuri
if语句的圆括号没有完整... 尽管即使我把它们放在那里对我也没有影响。 - Quintin Balsdon
这个不起作用,缺少括号,而且显然与Android插件不兼容?我一直收到一个关于未定义属性outputFile的错误。请看下面我的答案,展示了我如何解决它。 - William T. Mallard
有没有针对 .aab 文件的解决方案? - Rumit Patel

25

这将有助于您在2022年。

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

应用名称 FreeDebug.apk

证据 enter image description here

enter image description here


1
对我没用,它什么也没做。我添加了一个“println outputFileName”,并且它正确地打印出来了,但由于某种原因,Gradle没有使用“outputFileName”值作为文件名。顺便说一下,我正在尝试将其用于应用程序包而不是APK。 - thiagolr
2
在2021年使用Bundles时无法正常工作。 - chrjs
1
非常适用于APK。 - Slion
有没有针对 .aab 文件的解决方案? - Rumit Patel

10

对于 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"
    }
}

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

3
这个在 Android Gradle 3.0.0-alpha1 版本中已经无法使用了。看起来您不能再访问 outputFile 了。 - Sky Kelsey
如果您不想更新Gradle版本,这真的非常有用! - AtomicBoolean

7
我是这样做的:
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"));
                }

            }
        }
    }

1
outputFile 是什么? - IgorGanapolsky

3
这里是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");
            }
        }
    }
}

3

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

如果你在这里看第1346行,你会发现variantData.variantConfiguration.baseName用于outputFile。

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)变量没有大写。 - JJD
有什么想法如何完成这个任务? - JJD
(1) 根据BasePlugin.groovy-link中的第1316行,您可以更改project.archivesBaseNamevariantData.variantConfiguration.baseName以适应非对齐输出名称。但我不确定这是否会影响其他构建步骤。尽管如此,您不应该使用非对齐版本,而应该使用最终的apk(您可以完全控制apk名称)。(2) variant.name.capitalize() - Jelle

2

这是你需要的内容


android {
    defaultConfig {
        ……

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

1
这对我有用:
在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")

            }
        }
    }
}

0

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

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