# [Android Product Flavor](https://developer.android.com/studio/build/build-variants.html#product-flavors) ###### tags: `Android Gradle` ![](https://i.imgur.com/VAsIK0o.png) [TOC] # Introduction With **Product Flavor**, we can have **many versions of the same app** with slightly different variables/aspects in each. # Where to use it? All Product Flavor settings are set in **build.gradle** file , which is located in **app/build.gradle**. We can also put it in an apart .gradle file, while applying the file in the same **build.gradle (app/build.gradle)**. **Example:** ```java= apply from: '../variant.gradle' ``` >![](https://i.imgur.com/czAVHSF.png)[color=lightgreen] # How to set up? Having **build.gradle (app/build.gradle)** opened, we can either set it up on the **same file** or get a **separated .gradle file** ## Things to take into account before set up No matter either set up in build.gradle or separated .gradle file, all set ups must: 1. **be enclosed by android {}** 2. **specify flavorDimension "inputName" **Example:** ```java= android { flavorDimensions "productFlavor" productFlavors { flavor { } flavor1 { } } } ``` After **sync** you will see that **Build Variant** window will have more options in **Active Build Variant**. >![](https://i.imgur.com/scWhlek.png)[color=lightblue] ## Set up in build.gradle (app/build.gradle) 1. Open build.gradle(app/build.gradle) 2. Inside Android {} set up the product flavors 3. Sync Gradle >![](https://i.imgur.com/CZuC7Qr.png)[color=lightblue] ## Set up in separated .gradle file 1. New > File 2. Name the file with **.gradle extension** 3. Open build.gradle(app/build.gradle) 4. Link build.gradle to the newFile.gradle by using **apply from: 'location'** 5. Go to newFile.gradle 6. Set up product flavor **Note:** Remember to add **android {}** by yourself >![](https://i.imgur.com/ujUV1JH.png)[color=lightblue] # Product Flavor Information Profuct Flavor information can be set up by 3 methods: 1. **buildConfigField:** Values are shown in BuildConfig file. 2. **resValue:** Values are shown in res(generated) > values > gradleResValues. 3. **manifestPlaceholders:** Values can be used in manifest directly. ## **buildConfigField** This one will generate a file called **BuildConfig**, which will set up all constants set in gradle. ### **How to set up?** Just put **buildConfigField "type", "FieldName", "FieldValue"** Note: For String FieldValue a **\ (slash)** must be used. As we can see below, we can also set up **applicationId, versionCode, versionName** for each of our product flavor. **Example:** ```java= flavorDimensions "productFlavor" def BASE_URL = "BASE_URL" def APP_NAME = "APP_NAME" productFlavors { flavor { applicationId "com.zc.learngradle0" versionCode 2 buildConfigField "String", BASE_URL, "\"FieldValue\"" buildConfigField "String", APP_NAME, "\"AppName\"" buildConfigField "int", "FieldInt0", "0" } } ``` ### **BuildConfig File** >![](https://i.imgur.com/vVLZoOJ.png=500x400)[color=lightpink] >**Note:** Sync may not be enough for it to appear, you may need to run the project once. ### **What if your applicationId, versionCode, versionName did not change?** If you are **using another .gradle file** check the import place in build.gradle. As shown in the image below, check **build.gradle (app/build.gradle)** whether you have set up **defaultConfig** with the same fields as the one you have wrong in BuildConfig. If you did, check: * Whether you have really stated the variables in your variant. * Close BuildConfig, ReSync and Rebuild to check again If not, then it may be another issue. **Note:** DefaultConfig acts as default state when you did not specify the variables for any variant. ## **resValue** This one will show its values in **res(generated) > values > gradleResValues**. ### **How to set up?** ```java= flavorDimensions "productFlavor" productFlavors { flavor { // Will be put in res(generated) > values > gradleResValues // Note: res > values > strings.xml must not have same string id (Error: Duplicate resources) resValue "string", "base_url_base", "www.example.com" } } ``` ### **Output location: gradleResValues** **res(generated) > values > gradleResValues** >![](https://i.imgur.com/xVXTE6v.png)[color=pink] ## **manifestPlaceholders** Values generated can be used directly by **manifest by using ${constantName}**. ### **How to set up?** By setting an **array for manifestPlaceholders** we can set up **key-value** for each constant/variable we want. **Example:** ```java= flavorDimensions "productFlavor" productFlavors { flavor { manifestPlaceholders = [ "app_name": "FlavorApp", "app_icon": "@mipmap/ic_launcher", "app_round_icon": "@mipmap/ic_launcher_round" ] } } ``` ### **How to use the values set up in the manifestPlaceholder?** #### **In Manifest file** By using **${keyName}** we can call out the value set up in the manifestPlaceholder without any problem. ![](https://i.imgur.com/RD0RRHM.png) #### **In Project** If we want to retrive **manifestPlaceholder' values** in our project too, we have to use **meta-data** in manifest. >Be aware to put meta-data inside the Application section. [color=red] >**Note:** the meta-data name cannot use manifestPlaceholder values as name, meaning we cannot use name = ${...} >![](https://i.imgur.com/P1mc32P.png) **In Activity Retrive Example:** ```java= try{ PackageManager packageManager = getApplicationContext().getPackageManager(); ApplicationInfo appInfo = packageManager.getApplicationInfo(this.getPackageName(), PackageManager.GET_META_DATA); Log.d("manifestPlaceholder", appInfo.metaData.getString("app_icon")); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } ``` # Reference https://medium.com/stepstone-tech/how-to-build-17-apps-with-a-single-android-project-and-not-go-crazy-91d025adf0f0