Gradle - Only solution for changing application name based on build option

I am trying to modify the gradle file to allow different names for my Flavor and Build Type based application. So far I have been successful in terms of Flavor using Manifest Merging methods using Android gradle Plugin Docs

Current

These are the application names on my home screen for my debug and release constructs.

 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 

Close it, but ...

Desired

 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 need this so that I know what taste of debug is on my home screen. I'm not interested in the differentiation of tastes release , as the user will have only one on his device (maybe he can have several, but this does not concern me)

Given how extensible gradle is, I assume this is possible; however, I am not an advanced gradle user.

So, how can I (as much as possible) extend my code to get the desired result?

Note: the above tables use versionNameSuffix as a suffix for my application name; however, it could be anything (another added variable ??), which will allow me to tell what taste I use only in my debug build style.

Non-goals

Code

 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

 <manifest ...> <application ... android:label="${applicationLabel}" ... > 

Update

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

New outlet

 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) 
+5
source share
2 answers

The first attempt was closer to the correct answer than the updated code.

Further refactoring could be done by moving the entire manifestPlaceholders code inside the applicationVariants.all section; however, this is a working copy of the gradle -only blank 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 is executed applicationVariants.all { ... } , this is what all applicationLabel looks like. We are close, but we need to ADD ...

 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 applicationVariants.all { ... } code is executed applicationVariants.all { ... } , this is what all applicationLabel looks 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 

And ...

defaultConfig has no way to access information inside a separate productFlavors . Although defaultConfig is a Flavor type, only the specified Flavors can read information from defaultConfig . There is no mechanism to go the other way (what I know). Therefore you need to set the most common type in defaultConfig

Any information in the buildTypes block will receive the final word, and the code inside applicationVariants.all will not override this. To overcome this, you need to remove the necessary code from the buildType block and move it to the applicationVariants.all block (with the correct logical instructions)

+5
source

Christopher's solution did not work for me. I spent a few more hours trying different templates, and finally found one that worked in my case, so I will share it here.

Firstly, the definition of productFlavors 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" } } 

And last but not least: android: label in manifest> application:

  android:label="${appName}${appNameSuffix}" 

As a result, I get the following 6 options for the application name:

  • Pregnancy
  • Pregnancy UAT
  • Preg QA
  • Preg QA UAT
  • Preg debug
  • Preg Debug UAT

So, the conclusion is that I had to combine placeholder manifestors according to the taste of the product and the type of assembly in the manifest file, et voila!

Regarding cleanliness, readability and maintenance, I think this is the way :)

+3
source

All Articles