Read property file using BuildConfig Gradle

Bharath Kumar Bachina
2 min readJul 29, 2018

--

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=$1
cp -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 :)

--

--