Gradle combine Flavors + release/debug - android

I want use something like this, i know that's not possible, but i wanna know if have another way to use combine Flavor With build type
productFlavors{
demo{
release {
buildConfigField "String", "URL", '"192.1.1.1"'
}
debug {
buildConfigField "String", "URL", '"192.2.2.2"'
}
}
full{
release {
buildConfigField "String", "URL", '"192.2.2.2"'
}
debug {
buildConfigField "String", "URL", '"192.3.3.3"'
}
}
}

Rather than product flavors you can create multiple build types to suit your requirement.
for eg create build types like below
release {
buildConfigField "String", "URL", '"192.2.2.2"'
}
debug {
buildConfigField "String", "URL", '"192.3.3.3"'
}
releasedemo {
buildConfigField "String", "URL", '"192.1.1.1"'
}
debugdemo {
buildConfigField "String", "URL", '"192.2.2.2"'
}

Related

How to make BuildConfigField value dynamic in gradle?

I want to make HostName field dynamic. so I can have different HostName for both app1 and app2, for develop and release
**app1 {
dimension "client"
applicationId = "com.app1.random"
}
app2 {
dimension "client"
applicationId = "com.app2.random"
}
develop {
dimension "environment"
buildConfigField "String", "HOSTNAME", "\"https://app1.example.com\""
}
release {
dimension "environment"
buildConfigField "String", "HOSTNAME", "\"https://app1.com\""
}**
Hope this help you
flavorDimensions "default"
productFlavors{
develop {
buildConfigField "String", "HOSTNAME", "\"https://app1.example.com\""
}
release {
buildConfigField "String", "HOSTNAME", "\"https://app1.com\""
}
}

How to manipulate the product flavours of build.gradle through java code

I want to modify the token and API urls from my java code so that I can create a development or release build depending on mode selected from my custom screen.
Below is the code used in build.gradle
productFlavors {
dev {
buildConfigField "String", "TOKEN_URL", '"https://example.com"'
buildConfigField "String", "API_URL", '"https://api.ex"'
versionCode getDevVersionCode()
}
prod {
buildConfigField "String", "TOKEN_URL", '"https://release.example2.com"'
buildConfigField "String", "API_URL", '"https://api.release.ex"'
versionCode getReleaseVersionCode()
}
}
first in app/build.gradle, add the productFlavor under android
productFlavors {
qa {
buildConfigField "boolean", "LOG_HTTP", "true"
}
staging {
buildConfigField "boolean", "LOG_HTTP", "true"
}
live {
buildConfigField "boolean", "LOG_HTTP", "false"
}
}
then you need to create specific directories in app/src directory
finally, you just create a same name File in these different directories, like the following picture
in each ServerConstants(the name can be arbitrate), you should reference specific variables of "TOKEN_URL" and "API_URL"

define manifest place holders in build.gradle

I have a few manifest placeholders in my AndroidManifest.xml file
In build.gradle I want to dynamically populate those values depending on my flavor and build type.
How can I do that ?
I wrote a function that does the following
def getKey() {
def KeyToReturn = ""
android.applicationVariants.all { variant ->
printout("getKey: ${variant.name}")
def flavor = "default";
if (variant.productFlavors.size() > 0)
flavor = variant.productFlavors.get(0);
def buildType = variant.buildType.name
if (buildType == "debug" || buildType == "staging") {
if (flavor.name == "one") {
KeyToReturn = test_key_1
}
if (flavor.name == "two") {
KeyToReturn = test_key_2
}
}
if (buildType == "release") {
if (flavor.name == "one") {
KeyToReturn = live_key_1
}
if (flavor.name == "two") {
KeyToReturn = live_key_2
}
}
}
printout("KeyToReturn:" + KeyToReturn)
return KeyToReturn
}
I have this in my android.defaultConfig
defaultConfig {
minSdkVersion 15
targetSdkVersion 23
versionCode getVersionCode1()
versionName getVersionName1() + ""
manifestPlaceholders = [key: getKey()]
}
This is what my AndroidManifest.xml relevant part contains
<meta-data
android:name="key"
android:value="${key}"/>
The problem is when I look in the built AndroidManifest.xml file
the ${key} value is an empty string.
How do I populate this value correctly ?
You define manifest placeholders based on product flavors (and AFAIK build type) by adding them to the proper closure.
In this sample app, I use product flavors to use different rules for Android 7.0's network security configuration:
productFlavors {
thawte {
resValue "string", "app_name", "CA Validation Demo"
applicationId "com.commonsware.android.downloader.ca.thawte"
manifestPlaceholders=
[networkSecurityConfig: 'network_thawte']
buildConfigField "String", "URL", WARES
}
verisign {
resValue "string", "app_name", "Invalid CA Validation Demo"
applicationId "com.commonsware.android.downloader.ca.verisign"
manifestPlaceholders=
[networkSecurityConfig: 'network_verisign']
buildConfigField "String", "URL", WARES
}
system {
resValue "string", "app_name", "System CA Validation Demo"
applicationId "com.commonsware.android.downloader.ca.system"
manifestPlaceholders=
[networkSecurityConfig: 'network_verisign_system']
buildConfigField "String", "URL", WARES
}
pin {
resValue "string", "app_name", "Cert Pin Demo"
applicationId "com.commonsware.android.downloader.ca.pin"
manifestPlaceholders=
[networkSecurityConfig: 'network_pin']
buildConfigField "String", "URL", WARES
}
invalidPin {
resValue "string", "app_name", "Cert Pin Demo"
applicationId "com.commonsware.android.downloader.ca.invalidpin"
manifestPlaceholders=
[networkSecurityConfig: 'network_invalid_pin']
buildConfigField "String", "URL", WARES
}
selfSigned {
resValue "string", "app_name", "Self-Signed Demo"
applicationId "com.commonsware.android.downloader.ca.ss"
manifestPlaceholders=
[networkSecurityConfig: 'network_selfsigned']
buildConfigField "String", "URL", SELFSIGNED
}
override {
resValue "string", "app_name", "Debug Override Demo"
applicationId "com.commonsware.android.downloader.ca.debug"
manifestPlaceholders=
[networkSecurityConfig: 'network_override']
buildConfigField "String", "URL", SELFSIGNED
}
}
I can then reference the placeholder in the manifest normally:
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:networkSecurityConfig="#xml/${networkSecurityConfig}">

Android :connectedAndroidTest can't find symbol .. -> BuildConfigField gradle

I've set up some custom build tasks with gradle(Android Project), now those tasks work fine. Example of this task:
TEST {
buildConfigField "String", "KEY", "\"..\""
buildConfigField "String", "CLIENT_ID", "\"\""
buildConfigField "String", "PROTOCOL_VERSION", "\"5.0.0\""
buildConfigField "String", "BACKEND_ENVIRONMENT", "\"..\""
buildConfigField "String", "BACKEND_COUNTRY", "\"..\""
debuggable true
jniDebuggable true
signingConfig signingConfigs.debug
}
Now the problem is, that when I run the predefined task connectedAndroidTest it complains about missing variables in the code, which are the BuildConfigFields that aren't recognised. So my question how to work around this problem?
Thanks,
Define variables for debug buildType (just for debug builds)):
buildTypes {
debug {
buildConfigField "String", "KEY", "\"..\""
buildConfigField "String", "CLIENT_ID", "\"\""
buildConfigField "String", "PROTOCOL_VERSION", "\"5.0.0\""
buildConfigField "String", "BACKEND_ENVIRONMENT", "\"..\""
buildConfigField "String", "BACKEND_COUNTRY", "\"..\""
}
}
or in defaultConfig (for all builds):
defaultConfig {
buildConfigField "String", "KEY", "\"..\""
buildConfigField "String", "CLIENT_ID", "\"\""
buildConfigField "String", "PROTOCOL_VERSION", "\"5.0.0\""
buildConfigField "String", "BACKEND_ENVIRONMENT", "\"..\""
buildConfigField "String", "BACKEND_COUNTRY", "\"..\""
}

Is there a way to have a common section with buildConfigField and resValue in gradle?

I have a product with multiple product flavors like:
buildTypes {
debug {
}
release {
}
}
productFlavors {
flavor1 {
buildConfigField "String" "country" "se"
buildConfigField "String" "language" "sv-SE"
buildConfigField "String" "appName" "Flavor1"
}
flavor2 {
buildConfigField "String" "country" "se"
buildConfigField "String" "language" "sv-SE"
buildConfigField "String" "appName" "Flavor2"
}
flavor3 {
buildConfigField "String" "country" "se"
buildConfigField "String" "language" "sv-SE"
buildConfigField "String" "appName" "Flavor3"
}
flavor4 {
buildConfigField "String" "country" "se"
buildConfigField "String" "language" "sv-SE"
buildConfigField "String" "appName" "Flavor4"
}
flavor5 {
buildConfigField "String" "country" "se"
buildConfigField "String" "language" "no-NO"
buildConfigField "String" "appName" "Flavor5"
}
}
I would prefer a common section with all properties and only override those that are different. Is this possible?
I would also like to put all flavors (and perhaps buildTypes) in it's own file to make it more readable. So whenever you have to change a flavor, you can easily find it in its own file, and not have to scroll over thousands of line which it will be if I have all flavors and buildTypes together with all the rest in the main build file.
Selvin is correct, use the defaultConfig closure - there is no neater way! In the following example, flavors 1, 2 & 5 would set the default country and language to de. Flavors 3 & 4 override this with their own languages.
defaultConfig {
buildConfigField "String", "country", "de"
buildConfigField "String", "language", "de"
}
buildTypes {
debug {
}
release {
}
}
productFlavors {
flavor1 {
buildConfigField "String", "appName", "Flavor1"
}
flavor2 {
buildConfigField "String", "appName", "Flavor2"
}
flavor3 {
buildConfigField "String", "country", "uk"
buildConfigField "String", "language", "en_GB"
buildConfigField "String", "appName", "Flavor3"
}
flavor4 {
buildConfigField "String", "country", "fr"
buildConfigField "String", "language", "fr"
buildConfigField "String", "appName", "Flavor4"
}
flavor5 {
buildConfigField "String", "appName", name.capitalize()
}
}
NOTE
Just an FYI that you can use name.capitalize() to turn the name of any flavour, e.g. flavor5, into the app name of Flavor5 by using the capitalize() method - which will capitalize the first character in the String. However, this MUST go in the flavor, not defaultConfig

Categories

Resources