When developing an Android application, securely managing sensitive API keys such as the Google Maps API Key is crucial. Hardcoding API keys in strings.xml
or source code poses a security risk, as they can be easily extracted from decompiled APKs. Instead, we use Gradle properties and resValue
to inject the API key dynamically into the app while keeping it out of the source code repository.
In this blog post, we'll walk through how to securely manage and inject the Google Maps API key in an Android project, ensuring that it remains safe while still being accessible where needed.
Step 1: Store the API Key in secrets.properties
First, we store the API key in a local properties file that is not included in version control (Git) to prevent it from being leaked.
Create a file named secrets.properties
in the root directory of your project.
Add the following line (replace with your actual key):
GOOGLE_MAP_API_KEY=your_actual_google_maps_api_key
Add secrets.properties
to .gitignore
to ensure it is not committed to the repository:
secrets.properties
Now, the API key is stored securely and will not be pushed to GitHub or shared in version control.
Step 2: Load the API Key in build.gradle.kts
Since we need to use this API key within Gradle, we need to load it from secrets.properties
.
Modify the build.gradle.kts
file and add the following snippet before the android
block:
val localProperties = Properties()
val localPropertiesFile = File(rootDir, "secrets.properties")
if (localPropertiesFile.exists() && localPropertiesFile.isFile) {
localPropertiesFile.inputStream().use {
localProperties.load(it)
}
}
This snippet:
Loads the secrets.properties
file at runtime.
Extracts the GOOGLE_MAP_API_KEY
value.
Ensures the file exists before trying to read it, preventing crashes.
This must be placed at the top of build.gradle.kts
so that the properties are available before any build configurations.
Step 3: Inject the API Key into res/values/strings.xml
Using resValue
Instead of manually adding the API key to strings.xml
, we use resValue
in Gradle to inject it dynamically.
Modify your build.gradle.kts
inside the android
block:
android {
buildTypes {
getByName("debug") {
val googleMapsApiKey = localProperties.getProperty("GOOGLE_MAP_API_KEY") ?: ""
resValue("string", "google_maps_key", googleMapsApiKey)
}
getByName("release") {
val googleMapsApiKey = localProperties.getProperty("GOOGLE_MAP_API_KEY") ?: ""
resValue("string", "google_maps_key", googleMapsApiKey)
}
}
}
How resValue
Works
It injects the API key into the compiled res/values/strings.xml
at build time.
The key never appears in source code or XML files, reducing security risks.
The generated key can be accessed using @string/google_maps_key
Step 4: Use the API Key in AndroidManifest.xml
Since resValue
makes google_maps_key
available as a string resource, you can now reference it in AndroidManifest.xml
:
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
This ensures that Google Maps SDK can access the API key without hardcoding it anywhere in your project.
Step 5: Access the API Key in Kotlin Code (If Needed)
If you need to use the API key in Kotlin (for example, to initialize Google Maps dynamically), you can retrieve it as follows:
val apiKey = context.getString(R.string.google_maps_key)
This allows you to access the API key programmatically while keeping it securely stored.
Top comments (0)