Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a different manifestPlaceholder for each Build Variant

I will start by saying that I am very new to Gradle, so I apologize if this has already been answered.

I'm working on an Android application that uses an API key to access a 3rd party tool. A different API key needs to be used depending on both the flavor and build type of the app.

Here is a basic outline of what I'm trying to do:

android {     defaultConfig {         manifestPlaceholders = [ apiKey:"DEBUG_KEY" ]     }      buildTypes{         debug{             // Some debug setup         }         release{             // Some release setup         }     }      productFlavors {         // List of flavor options     }     productFlavors.all{ flavor->         if (flavor.name.equals("someFlavor")) {             if (buildType.equals("release")) {                 manifestPlaceholders = [ apiKey:"RELEASE_KEY_1" ]             } else {                 manifestPlaceholders = [ apiKey:"DEBUG_KEY" ]             }         } else {             if (buildType.equals("release")) {                 manifestPlaceholders = [ apiKey:"RELEASE_KEY_2" ]             } else {                 manifestPlaceholders = [ apiKey:"DEBUG_KEY" ]             }             }     } } 

So far the manifestPlaceholders statement is working in a very simple case, but I don't know how to reference the buildType from within the productFlavors block so that I can use it as a conditional.

like image 737
Stoph Avatar asked Jul 16 '15 17:07

Stoph


People also ask

When would you use product flavor in your build setup?

123 let's go Simply put, a product flavor is a variant of your app. It is very useful when you want to create multiple versions of your app. This means you can generate different versions or variants of your app using a single codebase.

How can you tell if a manifest is merged?

Inspect the merged manifest and find conflicts Even before you build your app, you can see a preview of what your merged manifest looks by opening your AndroidManifest. xml file in Android Studio, and then clicking the Merged Manifest tab at the bottom of the editor.

How do I create a build variant?

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.

What is a Buildtype in Gradle and what can you use it for?

Discussion. 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.


2 Answers

You may set manifestPlaceholders inside applicationVariants by accessing mergedFlavor for specific applicationVariant.

android.applicationVariants.all { variant ->     def mergedFlavor = variant.getMergedFlavor()     mergedFlavor.manifestPlaceholders = [appPackageId: "myPackageExample"] } 

If you're using the Kotlin DSL, you should use something like this:

android.applicationVariants.all { // don't put 'variant ->' here or you'll get the 'all' extension function     // no need to define 'mergedFlavor' because 'this' _is_ the variant so 'mergedFlavor' is already available.     mergedFlavor.manifestPlaceholders = ... } 
like image 101
Ali Avatar answered Sep 21 '22 18:09

Ali


I would guess that you are referring to Fabric ApiKey? :) I just spent hours trying to do it in a similar way with the placeholders and specifying the ApiKey in the gradle file although it does not seem possible as of com.android.tools.build:gradle:1.3.1. It is possible to specify a placeholder for a specific flavor but not for a flavor AND buildType.

Just to correct your syntax, the way you would have to do it (if it was possible) would be something like that but manifestPlaceholders are unknown to variants.

applicationVariants.all{ variant->     if (variant.productFlavors.get(0).name.equals("someFlavor")) {         if (variant.buildType.name.equals("release")) {             manifestPlaceholders = [ apiKey:"RELEASE_KEY_1" ]         } else {             manifestPlaceholders = [ apiKey:"DEBUG_KEY" ]         }     } else {         if (variant.buildType.name.equals("release")) {             manifestPlaceholders = [ apiKey:"RELEASE_KEY_2" ]         } else {             manifestPlaceholders = [ apiKey:"DEBUG_KEY" ]         }         } } 

What you actually need to do is to keep the key in the AndroidManifest.xml and handle it with multiple manifest file

src/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"           xmlns:tools="http://schemas.android.com/tools">         <application>             <meta-data             android:name="io.fabric.ApiKey"             android:value="DEBUG_KEY" tools:replace="android:value"/>     </application>     </manifest> 

src/someFlavorRelease/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"           xmlns:tools="http://schemas.android.com/tools">         <application>             <meta-data             android:name="io.fabric.ApiKey"             android:value="RELEASE_KEY_1" tools:replace="android:value"/>     </application>     </manifest> 

src/someOtherFlavorRelease/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"           xmlns:tools="http://schemas.android.com/tools">         <application>             <meta-data             android:name="io.fabric.ApiKey"             android:value="RELEASE_KEY_2" tools:replace="android:value"/>     </application>     </manifest> 

The manifestMerger will handle the replacement and you will end up with the proper key in every scenario. I just implemented it successfully. I just hope you were really referring to the Fabric key! :)

Hope this helps!

like image 24
Eric Labelle Avatar answered Sep 21 '22 18:09

Eric Labelle