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.
You may set manifestPlaceholders inside applicationVariants by accessing mergedFlavor for specific applicationVariant.
}
Similarly to the accepted answer, you could do it with string resources, if you didn't want to duplicate your manifests.
For example, if you had two flavors (flavor1 and flavor2) You'd end up w/ the following source sets.
You could then just use a string resource for your key value
One further optimization to keep all your keys in one place is to define them all in strings.xml in your main source set. and then have the flavor/build source sets reference those.
for example:
then in each of your flavor/build sourceSets, you just reference those keys.
flavor1Release/res/values/strings.xml
I believe that you need a manifestPlaceHolder to read that value in your Java code, right? If this is the case, you can already read the FLAVOR name in your generated BuildConfig.java. For example, if you define a flavor whose name is smartphone you can access that value using BuildConfig.FLAVOR String; then in your code you can use a simple
if (BuildConfig.FLAVOR.equals("smartphone"))...
But maybe you need to read a sort of configuration of your app, an apiKey. In that case, the best way to go is to create a Class or a string resource for every flavor; this is the link for you.
What i did is copied current
AndroidManifest.xml
intoapp/src/debug
and changed the key there debug Manifest :
app/src/main
Manifest is like :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.
What you actually need to do is to keep the key in the
AndroidManifest.xml
and handle it with multiple manifest filesrc/AndroidManifest.xml
src/someFlavorRelease/AndroidManifest.xml
src/someOtherFlavorRelease/AndroidManifest.xml
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!
I found this great solution in https://azabost.com/android-manifest-placeholders/
or