Waza_Be
Waza_Be

Reputation: 39558

MapActivity: set APIKey programmatically

I currently use a MapActivity in my application. I use it with 2 API Keys. One for debugging, and one for "production"

I am fed up with changing these values in the xml layout:

 <view class="com.google.android.maps.MapView" 
        android:id="@+id/myGmap" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:enabled="true"
        android:clickable="true"
        android:apiKey="@string/api_key_prod" />

I am fed up trying to change the apikey each time and replace prod by debug each time.

Is that possible to change this key within the onCreate() of my application.

Imagine that I have a boolean preference that look like: isDebug.

I may check thi preference on my phone and disable it by default on user application. and make something like:

 if (isDebug)
     myMap.setApiKey(R.string.api_key_debug)
 else
     myMap.setApiKey(R.string.api_key_prod)

Thank a lot for any help.

Upvotes: 22

Views: 13032

Answers (5)

Amin Soheyli
Amin Soheyli

Reputation: 651

For extra security put your API key and secrets in the local.properties file and access it using BuildConfig as follows:

  1. In your top-level settings.gradle file, include the Gradle plugin portal, Google Maven repository, and Maven central repository under the pluginManagement block. The pluginManagement block must appear before any other statements in the script.

    pluginManagement {
        repositories {
            gradlePluginPortal()
            google()
            mavenCentral()
        }
    }
    
  2. In Android Studio, open your project-level build.gradle file and add the following code to the dependencies element under buildscript:

    plugins {
        // ...
        id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1' apply false
    }
    
  3. Open your module-level build.gradle file and add the following code to the plugins element.

    plugins {
        //  ...
        id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
    }
    
  4. Save the file and sync your project with Gradle.

  5. Open the local.properties in your project level directory, and then add the following code. Replace YOUR_API_KEY with your API key.

    MAPS_API_KEY=YOUR_API_KEY
    
  6. Save the file.

    • Access the key within AndroidManifest.xml file: In your AndroidManifest.xml file, go to com.google.android.geo.API_KEY and update the android:value attribute with MAPS_API_KEY as follows:

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="${MAPS_API_KEY}" />
      
    • Access the key within Java/Kotlin code: Just use BuildConfig as follows:

        BuildConfig.MAPS_API_KEY
      

More can be found in docs.

Upvotes: 0

localhost
localhost

Reputation: 5598

You should use Product Flavors.

For example:

android {
    ...


    defaultConfig {
        minSdkVersion 8
        versionCode 10
    }


    productFlavors {
        dev {
            resValue "string", "google_maps_api_key", "DEV_API_KEY"
         }

        prod {
            resValue "string", "google_maps_api_key", "PROD_API_KEY"
         }
    }
}

Upvotes: 2

pete howard
pete howard

Reputation: 76

This works for me.

This variant of MapView constructor is documented here: https://developers.google.com/maps/documentation/android/reference/com/google/android/maps/MapView

@Override
protected void onCreate(Bundle arg0) {
    super.onCreate(arg0);
    String mapApiKey = <your choice logic here>
    mMapView = new MapView(this, mapApiKey);
    setContentView(mMapView);

Upvotes: 5

Vadim
Vadim

Reputation: 1602

You have to create google maps object dynamically. Your layout will contaion only parent layout for creating object.

Upvotes: 1

CommonsWare
CommonsWare

Reputation: 1006819

You cannot both have the widget in your layout and set the API key in Java.

If you dynamically create the MapView via its constructor, you can supply the API key that way from Java code, but then you will need to dynamically add it to your layout.

That being said, I'd deal with the problem via your build process (e.g., based on debug/production build, copy the right XML file into the right directory).

Upvotes: 8

Related Questions