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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25104323/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:05:43  来源:igfitidea点击:

How to customize the APK file name for product flavors?

androidgradleandroid-gradle-pluginbuild.gradleandroid-productflavors

提问by JJD

I am customizing the name of the APKfile of my Android application within the build.gradlescript as follows:

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

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

Now that I am using product flavors:

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

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

        blue {
            applicationId "com.example.myapplication.blue"
        }
    }
}

Is there a way to customize the name of each APK? I experimented with archiveBaseNameand baseNamewithout success. In the end I want to come up with the following files:

有没有办法自定义每个 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

回答by Lakshman Chilukuri

Try to put this in your android closure of build.gradle

尝试将其放在 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");
        }
    }
}

Now the outputs should be like green.apkand blue.apk.

现在输出应该像green.apkblue.apk

回答by notz

For Android Gradle Plugin 0.13.+ you should use something like this:

对于 Android Gradle Plugin 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);
            }
        }
    }
}

回答by Joao Cesar Stange

For Android Studio 3.0 you must change from:

对于 Android Studio 3.0,您必须从:

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

To:

到:

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

回答by user1252459

I did it like this:

我是这样做的:

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

            }
        }
    }

回答by Jelle

It's weird that you would need this because the apk filename is already differentby default.

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

If you look hereat line 1346, you can see that the variantData.variantConfiguration.baseName is used in the outputFile.

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

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

And the documentation for baseNameis

和文档baseName

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

So running gradle assembleFreeDebugshould get you a ProjectName-free-debug.apkfile.

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

But if that isn't the case, or you want a different filename, you can use the following code to customize it.

但如果情况并非如此,或者您想要不同的文件名,则可以使用以下代码对其进行自定义。

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

回答by Happy Singh

This will help you in 2020.

这将在 2020 年为您提供帮助。

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 name FreeDebug.apk

Apk 名称FreeDebug.apk

Proofenter image description here

证明在此处输入图片说明

enter image description here

在此处输入图片说明

回答by Daniel Wilson

Every answer here is the same, and outdated. It's easy to do [flavor]-[version]-[build type]:

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

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

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

If your versionName is "1.2.1", running gradle assemble will produce:

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

Green-1.2.1-debug.apk

Green-1.2.1-debug.apk

Green-1.2.1-release.apk

Green-1.2.1-release.apk

Blue-1.2.1-debug-apk

Blue-1.2.1-debug-apk

Blue-1.2.1-release.apk

Blue-1.2.1-release.apk

回答by Trinea

This is what you need

这就是你需要的

android {
    defaultConfig {
        ……

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

回答by Rui Correia

This work for me:

这对我有用:

Add the variant.productFlavors[0].namein the APK name.

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

Code example:

代码示例:

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

            }
        }
    }
}

回答by William T. Mallard

Here's my variant (heh) of Lakshman's answer above, not sure why I needed the "variants.outputs.each" but I did.

这是我上面 Lakshman 答案的变体(heh),不知道为什么我需要“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");
            }
        }
    }
}