Read property file using BuildConfig Gradle
Some times its very difficult to maintain all properties in build.gradle for different env.
Let say to we have 3 different env like dev, uat and prod and each one has 20 properties, then imagine our gradle file , how mess it is :(
Gradle brings lot of power to Android development. Using gradle script we can easily overcome this.
Let’s say you have app.properties file in your root folder and you want to access through buildConfig in your app
app.proprties
ENABLE_MOCK=false
APP_ID=com.test.app
BASE_URL=http://test.api.com:8080/
COUNTRY=IN
LANGUAGE=en
CURRENCY_CODE=INR
Now you can create one props.gradle file in gradle scripts like this.
import java.util.regex.Matcher
import java.util.regex.Pattern
def getCurrentFlavor() {
Gradle gradle = getGradle() def pattern = Pattern.compile("(?:.*:)*[a-z]+([A-Z][A-Za-z]+)")
def flavor = ""
gradle.getStartParameter().getTaskNames().any { name ->
Matcher matcher = pattern.matcher(name)
if (matcher.find()) {
flavor = matcher.group(1).toLowerCase()
return true
}
}
return flavor
}
def readDotEnv = {
def envFile = "android/app.proprties"
if (project.hasProperty("defaultEnvFile")) {
envFile = project.defaultEnvFile
}
if (System.env['ENVFILE']) {
envFile = System.env['ENVFILE']
} else if (project.hasProperty("envConfigFiles")) {
def flavor = getCurrentFlavor()
// use startsWith because sometimes the task is "generateDebugSources", so we want to match "debug"
project.ext.envConfigFiles.any { pair ->
if (flavor.startsWith(pair.key)) {
envFile = pair.value
return true
}
}
}
def env = [:]
println("Reading env from: $envFile")
try {
new File("$project.rootDir/../$envFile").eachLine { line ->
def matcher = (line =~ /^\s*(?:export\s+|)([\w\d.\-_]+)\s*=\s*['"]?(.*?)?['"]?\s*$/)
if (matcher.getCount() == 1 && matcher[0].size() == 3) {
env.put(matcher[0][1], matcher[0][2])
}
}
} catch (FileNotFoundException ignored) {
println("*** Missing app.properties file ****")
}
project.ext.set("env", env)
}
readDotEnv()
android {
defaultConfig {
project.env.each { k, v ->
def escaped = v.replaceAll("%", "\\\\u0025")
println("**** property key **** $k *** value $v ")
buildConfigField "String", k, "\"$v\""
resValue "string", k, "\"$escaped\""
}
}
}
And in your app build.gradle, just include like this
apply from: "../buildprops.gradle"
That's it :). And now In your app, you can directly access like this
val url = BuildConfig.BASE_URL
val country = BuildConfig.COUNTRY
Now, using shell script, let’ say copyProps.sh , you can copy properties file from different env to app root folder.
#!/bin/sh
set -e
set -x
ENV_CONFIG=$1cp -rf "configurations/"$ENV_CONFIG"/app.properties" "android/app.properties"
Now, Just run the shell script with the required config from your terminal
./scripts/copyProps.sh dev
That’s it :). Now we no need to worry about maintaining different environments in our gradle file.
Happy coding :)