Hide Secured Infomation in Android App
It’s important to hide your secured information in your Android apps, such as an API key or token. The local.properties is a great file to store this kind of information. It’s not a problem to store in a different file but you need to manually insert the file name into configuration.
— === M e n U === —
🍓 1. Why use local.properties?
🐾 2. Add a Property in Build.Gradle
🐩 3. Use the New Property
🐝 4. Other Choice: gradle.property
🍓 1. Why use local.properties? …… → Menu
Let’s open the Project View of your app, and open the .gitignore file.
→
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
Have you found the file? The local.properties file is ignored by default before you commit the change on the project. You’ll save an extra step to input a file in .gitignore.
🐾 2. Add a Property in Build.Gradle …… → Menu
We need to define a variable in Build.Gradle of the module.
Grab info from local.properties
plugins {...}
// get property from local.properties
def getProps(String propName) {
def propsFile = rootProject.file('local.properties')
if (propsFile.exists()) {
def props = new Properties()
props.load(new FileInputStream(propsFile))
return props[propName]
} else {
return "";
}
}
android {...}
Add API Info in local.properties
sdk.dir=...
APP_TOKEN="1234567890"
Add Variable in BuildConfig
android {
...
defaultConfig {
...
// BuildConfig: Type Var Value
buildConfigField("String", "APP_TOKEN", getProps('APP_TOKEN'))
Easy job!
🐩 3. Use the New Property …… → Menu
Hilt Module example in Kotlin:
import YOUR.PACKAGE.BuildConfig.APP_TOKEN
...
@Module
@InstallIn(SingletonComponent::class)
object ApiInterceptorModule {
@Provides
@Singleton
fun provideInterceptor(): Interceptor = Interceptor { chain ->
val requestBuilder = chain.request().newBuilder()
requestBuilder.header("Content-Type", "application/json")
requestBuilder.header("X-App-Token", APP_TOKEN)
chain.proceed(requestBuilder.build())
}
}
Usage: BuildConfig.Variable Name
😍: I can add as many constants as I like to in buildConfigField.
🐝 4. Other Choice: gradle.property …… → Menu
Let’s try to insert the secured information in a different file, such as gradle.property.
gradle.property
...
APP_TOKEN="1234567890"
build.gradle
Different with local.properties, you can save a step to import the value. Any settings in the gradle.property will directly import to gradle.
// APP_TOKEN from gradle.properties hidden in .gitignore
// BuildConfig: Type Var Value
buildConfigField("String", "APP_TOKEN", APP_TOKEN )
.gitignore
However, you need to add gradle.property in .gitignore.
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
gradle.properties
🤐 5. New Plugin — Secrets
The above method is the manual readable style. There is a new plugin which can save our works.
gradle.module — plugins
plugins {
...
id 'com.google.secrets_gradle_plugin' version '0.6'
}
gradle.module — secrets
secrets {}
You can set two type of files: default or specific file.
secrets —defaultProperties:
defaultPropertiesFileName 'local.defaults.properties'
secrets — properties:
propertiesFileName 'local.properties'
secrets — ignoreList:
In local.properties, there are some value we don’t need in the code, such as
sdk.dir=C\:\\Users\\Homan\\AppData\\Local\\Android\\Sdk
So, we can ignore that value.
ignoreList.add("sdk.*")
How to use them
In Kotlin:
Log.d(TAG, "Call local properties: ${BuildConfig.mapKey}")
In AndroidManifest.xml:
android:value="${mapKey}"