You wanna create an Android app that uses Twittet APIs, so yo need an API key and an API secrets only you and your apps know. Because you need these values inside you app, it’s easy and quick to write them down directly in your source code. But when you commit this code to GitHub (or any other public repo), practically you’re telling your secret keys to entire world. Seems uncommon? Unfortunately, not so much! Same for Dropbox SDK.
One simple way to avoid this bad practice is to store your values inside an environmental variable, so only your machine knows it, then read this values in some way and inject them in your code at build time.
Let’s see how to do that using Android Studio, Gradle, and BuildConfig.
First, we need to create these environmental vars. In Linux and Mac, create or edit the file ~/.gradle/gradle.properties (pay attention to the actual Gradle User Home directory position) and add some values:
#define your secret values TwitterConsumerKeyProp=xxxxxx66666666634333333ddddddTwitterConsumerSecretProp=3nkl3sds3skmslSDF394asdk39dmasd |
Second, in your module’s build.gradle file, add these lines
apply plugin: 'com.android.application' //Add these lines def TWITTER_CONSUMER_KEY = '"' + TwitterConsumerKeyProp + '"' ?: '"Define Twitter Consumer key"';def TWITTER_CONSUMER_SECRET = '"' + TwitterConsumerSecretProp + '"' ?: '"Define Twitter Consumer secret"'; android.buildTypes.each { type -> type.buildConfigField 'String', 'TWITTER_CONSUMER_KEY', TWITTER_CONSUMER_KEY type.buildConfigField 'String', 'TWITTER_CONSUMER_SECRET', TWITTER_CONSUMER_SECRET } |
Please note the “TwitterConsumerKeyProp” and “TwitterConsumerSecretProp” have to be the same in both Gradle settings file and Gradle build file.
Finally, to use these values in your code, filled at runtime by Gradle in the build script for you, simply use:
ConfigurationBuilder cb = new ConfigurationBuilder() .setDebugEnabled(BuildConfig.DEBUG) .setApplicationOnlyAuthEnabled(true) .setOAuthConsumerKey(BuildConfig.TWITTER_CONSUMER_KEY) .setOAuthConsumerSecret(BuildConfig.TWITTER_CONSUMER_SECRET); |
That’s all, then it’s up to you how to create more elaborated configurations. For example, you can have different values based on different android.buildTypes types, or the gradle settings file in a common network folder used by the entire team or…
Hi Alfredo, thanks for this post. Working on Windows, I created a gradle.properties file in c:users\.gradle
Worked like a dream.
Sorry for that, a bit got formatted out when posting. The correct path is c:usersme.gradlegradle.properties
It’s not working for me, i’m try in different way, but get error:
Error:(26, 0) No signature of method: static com.android.build.gradle.internal.dsl.BuildType.buildConfigField() is applicable for argument types: (java.lang.String, java.lang.String, java.lang.String) values: [String, API_KEY, LuzzaCqLceob5Xwz18xw]
Possible solutions: buildConfigField(java.lang.String, java.lang.String, java.lang.String), getBuildConfigFields()
Open File
What if I have multiple projects with different TwitterConsumerKeyProp ?
Should I use different names in the same ~\gradle.properties file like:
App1TwitterConsumerKeyProp=aaaaa66666666634333333dddddd
App2TwitterConsumerKeyProp=bbbbb66666666634333333dddddd
App2TwitterConsumerKeyProp=ccccc66666666634333333dddddd
or is there a way to define them in different files?
Thank you
Really good article. Its really good to store constant credentials in our own application without prior information providing to outside world. Thanks for sharing. :)