I am trying to modify my gradle file to allow for different names for my app based on Flavor
and Build Type
. So far, I have been successful in being concise with Flavor
based naming using Manifest Merging
techniques via the Android Gradle Plugin Docs
These are the names of the applications on my home screen for both my debug
and release
builds.
Flavor Debug App Name Release App Name
-------- -------------- ----------------
entity_1 App Name App Name
entity_2 App Name App Name
... ... ...
entity_2 App Name App Name
hub Hub Hub
Its's close, but...
Flavor Debug App Name Release App Name
-------- -------------- ----------------
entity_1 App Name - Entity_1_name App Name
entity_2 App Name - Entity_2_name App Name
... ... ...
entity_n App Name - Entity_n_name App Name
hub Hub Hub
I want this so I know which debug
flavor is which on my home screen. I don't care about differentiating on the release
flavors as a user will only have one on their device (it might be possible to have more than one, but I am not concerned with that)
Given how extensible Gradle is, I assume this is possible; however, I am not an advanced Gradle user.
So, how can I concisely (as possible) extend my code to get to my desired output?
Note: the above tables use versionNameSuffix
as a suffix for my app name; however, it can be anything (another added variable??) that will allow me to tell which flavor I am using only in my debug build type.
Not interested in String Resource
solutions as in the answer to Android/Gradle: App name based on build type *and* product flavor. A pure Gradle based solution is preferred.
Not interested in going away from the Manifest Merger
method that I have currently implemented. The answer at https://stackoverflow.com/a/28465883/2333021 is another way of implementing what I have already done, and does not allow me to only do this on the debug build (that I can see. If it does, then let me know).
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "..."
minSdkVersion 17
targetSdkVersion 23
versionCode 1
versionName "1.0"
manifestPlaceholders = [ applicationLabel:"App Name"]
}
productFlavors {
entity_1 {
versionNameSuffix ' - Entity_1_name'
applicationIdSuffix 'entity_1'
}
entity_2 {
versionNameSuffix ' - Entity_2_name'
applicationIdSuffix 'entity_2'
}
hub {
versionNameSuffix ' - Hub'
applicationIdSuffix 'hub'
manifestPlaceholders = [ applicationLabel:"Hub" ]
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
<manifest ...>
<application
...
android:label="${applicationLabel}"
... >
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
ext {
APP_NAME = "App Name"
HUB_NAME = "Hub"
}
defaultConfig {
applicationId "..."
minSdkVersion 17
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
productFlavors {
one_million {
versionNameSuffix ' - Entity_1'
applicationIdSuffix 'entity_1'
manifestPlaceholders = [ applicationLabel: APP_NAME + versionNameSuffix ]
}
udacity {
versionNameSuffix ' - Entity_2'
applicationIdSuffix 'entity_2'
manifestPlaceholders = [ applicationLabel: APP_NAME + versionNameSuffix ]
}
hub {
versionNameSuffix ' - Hub'
applicationIdSuffix 'hub'
manifestPlaceholders = [ applicationLabel: HUB_NAME ]
}
}
buildTypes {
release {
manifestPlaceholders = [ applicationLabel: APP_NAME ]
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
Flavor Debug App Name Release App Name
-------- -------------- ----------------
entity_1 App Name - Entity_1_name App Name
entity_2 App Name - Entity_2_name App Name
... ... ...
entity_n App Name - Entity_n_name App Name
hub Hub App Name <- Issue (Release)
You can change the build variant to whichever one you want to build and run—just go to Build > Select Build Variant and select one from the drop-down menu. To start customizing each build variant with its own features and resources, however, you'll need to know how to create and manage source sets.
All you need to do is add various build types in your module-level build. gradle file and during development or production, you can simply choose the Build Variant you want to test or release. NOTE: By default, the Android Studio will generate "debug" and "release" Build Types for your project.
A build type determines how an app is packaged. By default, the Android plug-in for Gradle supports two different types of builds: debug and release . Both can be configured inside the buildTypes block inside of the module build file.
The first try was a closer solution to the right answer than the updated code.
Further refactoring could possibly done by moving all the manifestPlaceholders
code inside the applicationVariants.all
section; however, this is a working copy of a semi-clean, gradle-only solution...
android {
ext {
APP_NAME = "App Name"
HUB_NAME = "Hub"
}
defaultConfig {
manifestPlaceholders = [ applicationLabel: APP_NAME ]
}
productFlavors {
entity_1 {
versionNameSuffix ' - Entity_1'
applicationIdSuffix 'entity_1'
}
...
entity_n {
versionNameSuffix ' - Entity_n'
applicationIdSuffix 'entity_n'
}
hub {
versionNameSuffix ' - Hub'
applicationIdSuffix 'hub'
manifestPlaceholders = [ applicationLabel: HUB_NAME ]
}
}
applicationVariants.all { variant ->
// Don't modify the release build or the hub flavor. They are good already.
if (variant.buildType.name == "release" || variant.flavorName == "hub") return
variant.mergedFlavor.manifestPlaceholders = [applicationLabel: APP_NAME + variant.mergedFlavor.versionNameSuffix]
}
Notes:
BEFORE the applicationVariants.all { ... }
code runs, this is what all the applicationLabel look like. We are close, but need to ADD to them...
Flavor Debug App Name Release App Name
-------- -------------- ----------------
entity_1 App Name App Name
entity_2 App Name App Name
... ... ...
entity_n App Name App Name
hub Hub Hub
AFTER the applicationVariants.all { ... }
code runs, this is what all the applicationLabel look like. We are done!
Flavor Debug App Name Release App Name
-------- -------------- ----------------
entity_1 App Name - Entity_1_name App Name
entity_2 App Name - Entity_2_name App Name
... ... ...
entity_n App Name - Entity_n_name App Name
hub Hub Hub
Also...
defaultConfig
does not have a way of accessing information within the individual productFlavors
. Although defaultConfig
is a Flavor
kind of, only the specified Flavors
can read information from within the defaultConfig
. There are no mechanism to go the other way (that I am aware of). So you need to set the most generic type in the defaultConfig
Any information within the buildTypes
block will get the final say, and the code within applicationVariants.all
will not override that. In order to overcome that, you have to remove the needed code from the buildType
block and move it within the applicationVariants.all
block (with the correct logic statements)
Christopher's solution didn't work for me. I spent another few hours trying different patterns, and I finally found one that worked in my case, so I'll share it here.
First, productFlavors definition in build.gradle:
productFlavors {
uat {
manifestPlaceholders.appNameSuffix = " UAT"
}
live {
manifestPlaceholders.appNameSuffix = ""
}
}
Then, buildTypes:
buildTypes {
debug {
manifestPlaceholders.appName = "Preg Debug"
}
qa {
manifestPlaceholders.appName = "Preg QA"
}
release {
manifestPlaceholders.appName = "Pregnancy"
}
}
Last but not least, android:label in manifest > application:
android:label="${appName}${appNameSuffix}"
As a result, I'm getting the following 6 variants of the app name:
So, the conclusion is, I had to concatenate manifest placeholders from product flavor and build type in the manifest file, et voila!
In terms of being clean, readable, and maintainable, I think this is the way to go :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With