Reputation: 1882
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
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:
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
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