JJD
JJD

Reputation: 51882

How to customize the APK file name for product flavors?

I am customizing the name of the APK file of my Android application within the build.gradle script as follows:

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 archiveBaseName and baseName without success. In the end I want to come up with the following files:

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

Upvotes: 55

Views: 34592

Answers (12)

J.Stange
J.Stange

Reputation: 518

For Android Studio 3.0 you must change from:

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

Upvotes: 10

Happy Singh
Happy Singh

Reputation: 1482

This will help you in 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"
    }
}}

Apk name FreeDebug.apk

Proof enter image description here

enter image description here

Upvotes: 28

Daniel Wilson
Daniel Wilson

Reputation: 19834

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:

Green-1.2.1-debug.apk

Green-1.2.1-release.apk

Blue-1.2.1-debug-apk

Blue-1.2.1-release.apk

Upvotes: 1

Trinea
Trinea

Reputation: 669

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

Upvotes: 2

Lakshman Chilukuri
Lakshman Chilukuri

Reputation: 1067

Try to put this in your android closure of 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");
        }
    }
}

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

Upvotes: 28

William T. Mallard
William T. Mallard

Reputation: 1660

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

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

Upvotes: 3

Rui Correia
Rui Correia

Reputation: 49

This work for me:

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

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

            }
        }
    }
}

Upvotes: 1

Golan Shay
Golan Shay

Reputation: 1269

I'm using the following so the files won't override each other:

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

Upvotes: 0

user1252459
user1252459

Reputation: 563

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

            }
        }
    }

Upvotes: 7

notz
notz

Reputation: 2467

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

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

Upvotes: 10

GrecoJava
GrecoJava

Reputation: 301

Android Gradle Plugin 0.13.0 has deprecated the outputFile that is used in:

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

The solution that is working for me is:

android {
... 
}

project.archivesBaseName = "AndroidAppGeneric-${_buildVersionNameForMaven}"

Upvotes: 0

Jelle
Jelle

Reputation: 919

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

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

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

And the documentation for baseName is

/**
 * 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 assembleFreeDebug should get you a ProjectName-free-debug.apk file.

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

Upvotes: 3

Related Questions