How to generate buildConfigField with String type
String type build config fields should be declared like this:
buildConfigField "String", "SERVER_URL", "\"http://dev.myserver.com\""
the field name in quotes, the field value in escaped quotes additionally.
Android BuildConfig Field generating String incorrectly
After writing this I have found the way, it seems that the values are printed in the same way they are defined so if you add escaped quotation marks to this it will work, example:
buildTypes {
release {
minifyEnabled false
buildConfigField("String", "PARSE_APP_ID", '"xxxxxxxxxxxxxxxxxxxxxxxx"')
buildConfigField("String", "PARSE_CLIENT_ID", '"xxxxxxxxxxxxxxxxxxxxxxxxx"')
buildConfigField("String", "FACEBOOK_APP_ID", '"999999999999999"')
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
After that, Rebuild and it will print the Strings values correctly:
public final class BuildConfig {
....
// Fields from build type: debug
public static final String FACEBOOK_APP_ID = "999999999999999999";
public static final String PARSE_APP_ID = "xxxxxxxxxxxxxxxxxxxxxxxxxxx";
public static final String PARSE_CLIENT_ID = "xxxxxxxxxxxxxxxxxxxxxxxx";
}
How to define a shared build variable?
You can put your common buildConfigField
in defaultConfig
:
android {
defaultConfig {
buildConfigField "string", "SHARED_URL", "https://stackoverflow.com/"
}
buildTypes {
debug {
buildConfigField "string", "PRIVATE_URL", "https://debugoverflow.com/"
}
release {
buildConfigField "string", "PRIVATE_URL", "https://releaseoverflow.com/"
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
SHARED_URL
will now be available for all build variants.
Gradle buildConfigField with integer variable
I found a solution, so maybe this answer will help somebody in future.
def String globalVersionCode
defaultConfig {
applicationId "com.test.gradle.build"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "0.1"
globalVersionCode = versionCode
}
buildTypes {
release {
buildConfigField ("int", "DatabaseVersion", globalVersionCode)
}
}
And now in java I can get DatabaseVersion variable:
public static final int DB_VERSION = BuildConfig.DatabaseVersion;
Define buildConfigField for androidTest
You have to pass it as a parameter to connectedAndroidTest
task.
android {
...
buildTypes {
prod {
buildConfigField "String", "BASE_URL", "\"${getBaseUrl("abc.com")}\""
}
debug {
buildConfigField "String", "BASE_URL", "\"${getBaseUrl("efg.com")}\""
}
}
}
def getBaseUrl(String fallback) {
return project.hasProperty("base_url") ? project.getProperties().get("base_url") : fallback
}
Then passing parameters via -P
:
./gradlew connectedDebugAndroidTest -Pbase_url="xxx.com"
./gradlew connectedProdAndroidTest -Pbase_url="yyy.com"
Gradle buildConfigField: Syntax for arrays & maps?
For array
app.gradle
buildConfigField "String[]", "URL_ARRAY",
"{" +
"\"http:someurl\"," +
"\"http:someurl\"," +
"\"http:someurl\"" +
"}"
For Map
buildConfigField "java.util.Map<String, String>", "NAME_MAP",
"new java.util.HashMap<String, " +
"String>() {{ put(\"name\", \"John\"); put(\"name1\", \"John\"); put(\"name2\", " +
"\"John\"); }}"
Access in code:
HashMap<String, String> name = (HashMap<String, String>) BuildConfig.NAME_MAP;
buildConfigField for collection by reading .properties file
I created gradle function in order to generate texted-inline-function.
The example.properties assumes the data types are in <String, Boolean>
pair.
example.properties
example1 = true
example2 = false
gradle function
android {
defaultConfig {
// read file from project root folder
buildConfigField 'java.util.Hashtable<String, Boolean>', 'PropertyPairs', makePropertyHashTable(getRootDir().getPath() + File.separator + 'example.properties')
}
}
def makePropertyHashTable(filename) {
def devProperties = new Properties()
try {
devProperties.load(new FileInputStream(file(filename)))
} catch (FileNotFoundException e) {
devProperties = null
System.out.println('devProperties value is null')
}
// result example: new Hashtable<String, Boolean>(){{ put(true, "a"); }};
def prefix = 'new java.util.Hashtable<String, Boolean>(){{ '
def suffix = '}}'
def value = ''
if (devProperties != null) {
for (d in devProperties) {
value += String.format('put("%s",%s); ', d.key, d.value)
}
}
}
return String.format('%s%s%s', prefix, value, suffix)
}
In application code usage
if (BuildConfig.PropertyPairs.getOrDefault("example1", false) == true) {
// do something
}
buildConfigField not working after updating gradle to 7.0.3
It's unclear how the build tools determine the order of the field declarations in the BuildConfig. What works though is this (note the BuildConfig.BACKEND_HOST
instead of just BACKEND_HOST
):
buildConfigField 'String', 'BACKEND_HOST', 'my.backend.host.com'
buildConfigField 'String', 'APPLICATION_LIST_URL', 'BuildConfig.BACKEND_HOST + "/page"'
Chapter 8.3.3 of https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html explains what forward references are legal and which ones are illegal.
Here's a minimal code sample showing how the BACKEND_HOST can be defined in each flavor:
defaultConfig {
applicationId "com.example.myapplication"
minSdk 30
targetSdk 31
versionCode 1
versionName "1.0"
buildConfigField 'String', 'APPLICATION_LIST_URL', 'BuildConfig.BACKEND_HOST + "/page"'
}
flavorDimensions "version"
productFlavors {
free {
dimension "version"
buildConfigField "String", "BACKEND_HOST", '"www.free.com"'
}
paid {
dimension "version"
buildConfigField "String", "BACKEND_HOST", '"www.paid.com"'
}
}
This works because more specific BuildConfig fields (flavors) are evaluated first before the less specific ones (defaultConfig).
This code is copied from the OP's question and modified to compile by making the references to BACKEND_HOST
static:
defaultConfig {
applicationId "my.app.id"
minSdkVersion 21
versionCode getBuildTimestamp()
versionName "2.0.0"
buildConfigField 'String', 'APPLICATION_LIST_URL', 'BuildConfig.BACKEND_HOST + "/page"'
buildConfigField "String", "BACKEND_HOST", '"www.paid.com"'
}
flavorDimensions "type"
productFlavors {
local {
dimension "type"
targetSdkVersion 30
buildConfigField 'String', 'APK_DOWNLOAD_RESOLVE_URL', 'BuildConfig.BACKEND_HOST + "DOES_NOT_EXIST"'
}
remote {
dimension "type"
targetSdkVersion 30
applicationIdSuffix ".remote"
buildConfigField 'String', 'APK_DOWNLOAD_RESOLVE_URL', 'BuildConfig.BACKEND_HOST + "/remote/download"'
}
}
def backendRemote= '"https://myUrl"'
android.applicationVariants.all {
variant ->
def backendHost = backendRemote
variant.buildConfigField "String", "AUTH_HOST", backendHost
variant.buildConfigField "String", "BACKEND_HOST", backendHost
}
Android Studio gradle buildConfigField setup
That could be defined in any of the gradle.properties
files:
- In the module root
- In the project root
- In the Gradle home (e.g.,
~/.gradle
on Linux and macOS)
There's also a syntax for using environment variables to inject values like that, but that approach didn't use to work with Android Studio, and I am not aware that it now does. It would work for command-line builds (e.g., CI servers).
I think that there is a command-line switch approach as well for defining properties like these.
Personally, I use gradle.properties
.
Related Topics
Activity Not Started, Its Current Task Has Been Brought to the Front
Android Play Services 6.5: Locationclient Is Missing
File Res/Drawable/Abc_Ic_Ab_Back_Material.Xml from Drawable Resource Id #0X7F020016
Gcm Service_Not_Available on Android 2.2
Firebase Auth Using Phone Number and Password
How to Send File Using Bluetooth on Android Programatically
How to Handle Ontouch Event for Map in Google Map API V2
Android: Disable Soft Keyboard at All Edittexts
Android - How to Enable Autostart Option Programmatically in Xiaomi Devices
How to Send JSON Object to Server Using Volley in Android
How to Get the Fragment Instance from the Fragmentactivity
Android Path to Asset Txt File
Android Place Picker Closes Immediately After Launch
How to Listen to Doubletap on a View in Android
How to Change Bitmap Image Color in Android
Setresult Does Not Work When Back Button Pressed
How to Set "Android:Layout_Below" at Runtime Programmatically