Manage Google Maps API Key with Gradle in Android

2019-01-10 05:37发布

问题:

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]" />
-->

回答1:

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.



回答2:

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.



回答3:

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.



回答4:

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:

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.