Android: automatically selects debug / release Maps api key?

OBSOLETED: This old question relates to the deprecated Google Maps v1 API. When using API v2, you can use multiple certificate fingerprints in a single Google API Console entry. The API key is no longer stored in the manifest or code.




Can I automatically determine which certificate was used to sign the APK? I would like to have both debug and issue Map certificates in the application and pass them to the MapView constructor.

With this setting, I’m not mistaken when releasing the application - I use the debug certificate on the emulator and my device, and then subscribe to the release before sending the application to the market.

I was thinking about discovering my particular device or if the debugger is connected, but it is not perfect. Maybe some debugging of files is required to check debugging? Is there a better way?

+40
android debugging google-maps key android-mapview
Jun 12 '10 at 19:16
source share
11 answers

There is a new way to determine if this is a debug build or release in SDK Tools edition 17 . Excerpt from a review of new features:

Assemblies now generate a class called BuildConfig that contains the DEBUG constant, which is automatically set according to your assembly type. You can check the constant ( BuildConfig.DEBUG ) in your code to run debug-only functions.

So now you can just write something like this:

if (BuildConfig.DEBUG) { //Your debug code goes here } else { //Your release code goes here } 

UPDATE: I encountered an error in ADT: sometimes BuildConfig.DEBUG is true after exporting the application package. Description is here: http://code.google.com/p/android/issues/detail?id=27940

+45
Mar 24 '12 at 8:26
source share

Had the same problem with the API key. Here's a complete solution based on the link above and an example from Bijarni (which for some reason did not work for me), I am now using this method:

 // Define the debug signature hash (Android default debug cert). Code from sigs[i].hashCode() protected final static int DEBUG_SIGNATURE_HASH = <your hash value>; // Checks if this apk was built using the debug certificate // Used eg for Google Maps API key determination (from: http://whereblogger.klaki.net/2009/10/choosing-android-maps-api-key-at-run.html) public static Boolean isDebugBuild(Context context) { if (_isDebugBuild == null) { try { _isDebugBuild = false; Signature [] sigs = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures; for (int i = 0; i < sigs.length; i++) { if (sigs[i].hashCode() == DEBUG_SIGNATURE_HASH) { Log.d(TAG, "This is a debug build!"); _isDebugBuild = true; break; } } } catch (NameNotFoundException e) { e.printStackTrace(); } } return _isDebugBuild; } 

You should find out your hashValue () debugging signature once, just print sigs [i] .hashCode ().

Then I did not want to dynamically add MapView, but rather use an xml file. You cannot set the api key attribute in the code and use the xml layout, so I use this simple method (although copying the xml layout is not so pretty):

In my MapActivity:

  public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Select the proper xml layout file which includes the matching Google API Key if (isDebugBuild(this)) { setContentView(R.layout.map_activity_debug); } else { setContentView(R.layout.map_activity_release); } 
+26
Sep 30 '10 at 8:11
source share

An easier way to determine if this is a debug build is to check the debug flag on the application information than a hash signature.

 public boolean isDebugBuild() throws Exception { PackageManager pm = _context.getPackageManager(); PackageInfo pi = pm.getPackageInfo(_context.getPackageName(), 0); return ((pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0); } 

After you discover the debug assembly, you can use another resource to display the map or create a map in the application and add it to the layout.

  if(isDebugBuild()) { _mapView = new MapView(this, getString(R.string.debugmapskey)); } else { _mapView = new MapView(this, getString(R.string.releasemapskey)); } 
+10
May 16 '11 at 21:56
source share

I worked on a terrible incorrect integration of api keys in the process of building and managing source code by creating its property stored in local.properties . I had to add the following to build.xml :

 <property name="mapviewxml" value="res/layout/mapview.xml" /> <target name="-pre-build"> <fail unless="mapsApiKey">You need to add mapsApiKey=... to local.properties</fail> <copy file="mapview.xml.tpl" tofile="${mapviewxml}" overwrite="true"> <filterchain> <replacetokens> <token key="apiKey" value="${mapsApiKey}"/> </replacetokens> </filterchain> </copy> </target> 

Now, of course, I had to create mapview.xml.tpl in my root project (it cannot go to res/layout because it will break the build process):

 <?xml version="1.0" encoding="utf-8"?> <com.google.android.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" android:apiKey="@apiKey@" /> 

During pre-compilation, the template is copied to the right place, and @apiKey @ is replaced with the real key. Unfortunately, I did not find a way to distinguish between debug and release assemblies at this stage, so for compilation for release, I just add apiKey for release to the ant parameters:

 ant -DmapsApiKey=.... release 

This approach integrates well with SCM (I do not need to verify the keys) and is acceptable with the build process.

+3
Dec 12 '10 at 9:57
source share

If you're still interested, I just wrote about another way to do this. With a simple change in the Android build script, you can switch the map API key, as well as all other necessary release changes. What I like about this is that the release does not include debugging, and you can store the XML layouts just like before.

http://blog.cuttleworks.com/2011/02/android-dev-prod-builds/

+3
Feb 01 '11 at 3:00
source share

I think that creating an entry in the Google API console that includes both the release key and your debug key (both mappings to the same package) works fine, and this is a much simpler way to not worry about you debug or compile release version. The solution is presented here.

+3
Aug 31 '13 at 5:47 on
source share

All answers here look deprecated if you are using android studio then gradle is the way to go

Use different keys in build.gradle file

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

source

And if you want to save multiple passwords for debugging and release in different ways, you should follow this

+2
Mar 30 '16 at 13:15
source share

I got a special file on the SD card - if there is, use the debug key; missing - use release one. And it works.

EDIT: see the new accepted answer, it works better

+1
Jun 13 '10 at 23:15
source share

I don't know if this helps anyone, but I combined some other suggestions here to create the next MapViewActivity.

In this example, R.layout.map_dbg is used only if it is a debug assembly and the file exists (add this file to your .gitignore).

The advantages of this approach are as follows:

  • you do not need to write an ant target (well, if you use eclipse)
  • the correct release key is always in map.xml (I hope that the debug key will not be checked by mistake)
  • the release key is always used to build the release.
  • You can use several debug keys

The disadvantages of this approach include:

  • you need to remember to update map_dbg.xml every time map.xml is updated

     public class MapViewActivity extends MapActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // // copy the map.xml to map_dbg.xml and update the api key. // int id = getLayoutId("map_dbg"); if(id ==0) id = R.layout.map; setContentView(id); } int getLayoutId(String name) { return isDebugBuild() ? getResources().getIdentifier(name, "layout", getPackageName()) : 0; } public boolean isDebugBuild() { boolean dbg = false; try { PackageManager pm = getPackageManager(); PackageInfo pi = pm.getPackageInfo(getPackageName(), 0); dbg = ((pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0); } catch (Exception e) { } return dbg; } } 
+1
Aug 12 '11 at 16:22
source share

I have a simple ant target set, which replaces apikey with either a debug key or a release key. It is really simple, and the code does not contain unwanted logic.

 <target name="apikey"> <!-- Location of target layout file --> <first id="first"> <fileset dir="." includes="res/layout/kondi_training_templates.xml" /> </first> <property name="layout-file" value="${toString:first}"/> <echo>template-file: ${template-file}</echo> <replaceregexp file="${template-file}" match="android:apiKey=.*" replace='android:apiKey="${mapview.apikey}"' byline="true" /> </target> 
0
Jan 22 '13 at 12:28
source share

Map V2 Easily send individual keys using the Android Studio Gradle tool. I applied a simple way for this. Please check the link here .

0
Sep 01 '16 at 13:19
source share



All Articles