Hemã Vidal
Hemã Vidal

Reputation: 1882

How to configure extra properties to load in a android app initialization?

I want to setup a variable SERVER_URL and it'll be switched between environments production, test, development.

What I want to do:

@Override
protected void onCreate(Bundle bundle) {
    R.urls.SERVER_URL; // is it a valid approach using resources?
}

Is there a way to switch environments(dev, prod, test) without change the code?

What's the best approach to implement this behavior?

Is there a way to configure it in the playstore my variable(SERVER_URL) or must I implement only in code?

Upvotes: 0

Views: 1600

Answers (2)

Tam Huynh
Tam Huynh

Reputation: 2477

There are 2 ways you can do it:

1/ By string resource like you want

Add a resource file called secret_keys.xml or whatever name to separate it from other resources file. Put your keys, api endpoints here as the normal string resource, remember to add translatable="false" if you don't want to mess with localization.

Place that file in app/debug/res/values/. Create a new debug folder if it doesn't exist. Do the same for staging or release, Android will automatically use the folder with the same name as the build type.

2/ By properties files

Create 3 .properties files and put your keys inside: enter image description here

HOST="http://api.blablabla.com"
CLIENT_ID="hahaha"
CLIENT_SECRET="hehehe"

Bind it to BuildConfig variable in your app build.gradle, do the same for other build types:

def getPropertiesFile = { path ->
    Properties properties = new Properties()
    properties.load(new FileInputStream(file(path)))
    return properties
}

android {
    ...

    buildTypes {
        debug {
            ...

            getPropertiesFile('./config/development.properties').each { p ->
                buildConfigField 'String', p.key, p.value
            }
        }
        ...
    }
}

In your app just call BuildConfig.HOST to get the string you want

UPDATE

Ignore these config files in .gitignore:

app/config
secret_keys.xml

Upvotes: 1

Sagar
Sagar

Reputation: 24917

You can use different approaches. Ideally you shouldn't change URL at Runtime to minimize the attack surface. This approach could have direct impact on your app's security.

If your target is to modify this URL without touching code, you can do can bind this value at Compile time. You can create application.properties file and modify this file for different target builds (dev,production,test). In your code, you can read the values from properties file instead of hardcoded value. You can place this file in your assets folder and apply necessary obfuscation. This way only the properties file will change and your app's security remains intact.

Another way would be provide this parameter at build time (when you execute gradlew command). You can add commandline parameters which would be added to BuildConfig. In your code, you can simply refer to URL by calling BuildConfig.SERVER_URL. You can follow this SO to achieve this.

In either case I would recommend you to bind this value at compile time.

Upvotes: 0

Related Questions