Manage Google Maps API Key with Gradle in Android Studio

AndroidGradleAndroid StudioKeyGoogle Maps-Android-Api-2

Android Problem Overview


I know Gradle is powerful and I would like to manage the API keys for development/produciton of Google Maps

Currently I always need to manually comment one line and uncomment the other to make it work. Is there a way to do it automatically in Gradle with some custom release configuration ?

<!-- MapView v2 API -->
<uses-library android:name="com.google.android.maps" />
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="[MY_DEV_KEY]" />
<!-- PROD
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="[MY_PROD_KEY]" />
-->

Android Solutions


Solution 1 - Android

Since you are using gradle you can do the following:

build.gradle

android {
  .. .. ...
    buildTypes {
       debug {
          resValue "string", "google_maps_api_key", "[YOUR DEV KEY]"
       }
       release {
           resValue "string", "google_maps_api_key", "[YOUR PROD KEY]"
       }
    }
  }

And in your AndroidManifest.xml

<meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="@string/google_maps_api_key"/>

This way you only have one AndroidManifest.xml and you set value based on your build type. Hope this helps.

Solution 2 - Android

You can achieve this with manifest placeholder feature: http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger#TOC-Placeholder-support

in build.gradle file:

buildTypes {
    debug {
        manifestPlaceholders = [ google_map_key:"your_dev_key"]
    }
    release {
        manifestPlaceholders = [ google_map_key:"prod_key"]
    }
}

and then in manifest:

<meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="${google_map_key}"/>

That's exact thing for different keys for different flavors and this is cleaner solution than using string resources.

P.S. On the other hand I would better consider getting api keys from backend and do not hardcode them on the client. This is more secure and more flexible approach.

Solution 3 - Android

In Android Studio (checked with version 0.8.11) you can add Google Maps Activity (New->Google->Google Maps Activity) to your project and Android studio will generate necessary files for you, you only have to insert your keys. There are also instructions generated. Look for google_maps_api.xml files in your debug/res/values/ and release/res/values folders.

Solution 4 - Android

In Android Studio, there's the concept of build types and flavors, and you can use these to get what you need. Build types are different versions of the app that are functionally identical but may differ in debugging code. By default, all Android Gradle projects have debug and release build types.

Flavors are versions of your app that are functionally different; you can have free and paid, for example. By default your Android Gradle projects don't have any flavors, but you can add them.

Build types and flavors are combined (into what's called a variant) when you do a build; in this example, you can have freeDebug, freeRelease, paidDebug, and paidRelease builds.

The build system lets you easily override a number of things in each type/flavor/variant; one of the things you can do is to override parts of the AndroidManifest.xml file. The build system merges together the different eligible bits of manifests into one master manifest when it builds a particular variant.

With that background in hand, in your case you might want to have a different API key in the debug version of your app vs. the release version. The debug version is what you'll use in your day-to-day development, debugging and testing, and the release version is what you'd deploy to users.

To do this, do not put the Google Maps API key in the main app's AndroidManifest.xml file in src/main; instead, add two new folders, src/debug and src/release and add stub AndroidManifest.xml files there. Don't include full information in those new manifests, but only what's unique about what's needed for that particular variant. Your source files will look like this:

Screenshot of project directory structure showing multiple manifest files

Your src/debug/AndroidManifest.xml file will contain this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="[MY_DEV_KEY]" />
</manifest>

and src/release/AndroidManifest.xml will have this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="[MY_PROD_KEY]" />
</manifest>

To reiterate, don't put any API key in the src/main/AndroidManifest.xml file.

If for some reason you don't want to use build types to differentiate you could set up dev and prod flavors and split it that way instead; the manifest overriding works in the same way.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHrkView Question on Stackoverflow
Solution 1 - AndroidbondView Answer on Stackoverflow
Solution 2 - AndroidIlyaEreminView Answer on Stackoverflow
Solution 3 - AndroidOkasView Answer on Stackoverflow
Solution 4 - AndroidScott BartaView Answer on Stackoverflow