What's this?

WhereBlogger is a tool for Android phones, for keeping a location-based journal.

WhereBlogger can automatically collect GPS points for you, or you can add them manually. When an internet connection is available, maps will be downloaded for each logged point, and you can annotate each point with a title and a longer description. The program aims to be kind to your phone's battery and does not require a data connection or switch the GPS on at random times, as both electricity and data can be scarce while traveling.

Everything recorded by WhereBlogger can be published online (to a blog of your choice), or exported to the SD-card and copied to your PC to use as you see fit.

You can download WhereBlogger from the Android market (or just view the listing here).

Tuesday, October 27, 2009

Choosing an Android Maps API key at run-time

This is a little hint for any Android developers out there.

When using the Google MapView component in an Android app, you need a Maps API key which matches your app's signature. This is all fine and dandy, and pretty well explained on Google's web site.

However, a side-effect of how this is done means most developers are working with two different signatures on a daily basis: the signature of the debug key, which is autogenerated by the Android SDK, and their "production" signature which they use for publishing their apps to the market. Working with two signatures means you need two different Maps API keys as well, one for debugging and another for releases.

I didn't want to have to hand-edit constants in my code each time I built a release, and couldn't find any hints online on a more elegant solution, so I came up with the following snippet of code. This code will, at run-time, check which key was used to sign the app and then choose between two Maps API keys, based on whether it is a debug key or not.

static final String DEBUG_TAG = "YourApp";
static final String DEBUG_SIG = "...";
static final String DEBUG_KEY = "DEBUG KEY GOES HERE";
static final String RELEASE_KEY = "RELEASE KEY GOES HERE";
static String staticMapsApiKey = null;
public static String getMapsApiKey(Context context) {
if (staticMapsApiKey == null) {
try {
staticMapsApiKey = RELEASE_KEY;
Signature [] sigs = context.getPackageManager()
.getPackageInfo(context.getPackageName(),
PackageManager.GET_SIGNATURES)
.signatures;
for (int i = 0; i < sigs.length; i++) {
MessageDigest sha = MessageDigest.getInstance("SHA-1");
sha.update(sigs[i].toByteArray());
byte [] digest = sha.digest();
String str = "";
for (int di = 0; di < digest.length; di++) {
str += Byte.toString(digest[di])+":";
}
Log.d(DEBUG_TAG, "Got key sig: " + str);
if (str.equals(DEBUG_SIG)) {
Log.d(DEBUG_TAG, "Oh look, a debug signature!");
staticMapsApiKey = DEBUG_KEY;
break;
}
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
return staticMapsApiKey;
}

This code is admittedly rather ugly - a more experienced Java developer would probably write something a bit more elegant. But it gets the job done, once you have filled in all the constants at the top. The DEBUG_KEY and RELEASE_KEY strings should contain the keys you get from Google. The DEBUG_SIG constant can be filled in by running the code in debug mode, and searching the output of "adb logcat" for the "Got key sig: " message.

Hope this helps someone, and if anyone knows of a more elegant solution, please let me know!

Update: Sure enough, someone came up with a more elegant solution, based on this one. Cool! :-)

23 comments:

  1. Hy Bjarni,
    How can I get RELEASE_KEY from google?
    Thanks.

    ReplyDelete
  2. Not sure how to make clickable links in comments here, but this is the page you want:

    http://code.google.com/android/add-ons/google-apis/mapkey.html

    ReplyDelete
  3. Thanks Bjarni, but I still not understanding this:

    " Note that, when you are ready to publish your application, you must get a Maps API Key that is based on the certificate that you will use to sign the application for release. You must then change the Maps API Key strings referenced by all of your MapView elements, so that they reference the new Key. "

    ReplyDelete
  4. When developing an Android app, you will generally be building APKs signed with a 'debug certificate'.

    When you publish an app to the market, you will sign your APKs with a different certificate. Read the Android docs on publishing for details on how this works, I think this may be what is confusing you.

    Last I checked, the Maps API key is linked to the certificate and my code snippet above eliminates the need to make the change described by Google in the text you quoted - instead you want to invoke my function wherever you would otherwise have referenced the constant key.

    ReplyDelete
  5. Your example helped me to get on the right track, thanks! Had some issues, so simplified it a bit (basically just using the signature object's hash value) and to use different xml layouts instead of adding the view from the code.

    Full example here: http://stackoverflow.com/questions/3029819/android-automatically-choose-debug-release-maps-api-key/3828864#3828864

    ReplyDelete
  6. Thanks for the update, Bachi, glad my post helped!

    I've updated my post with a link to your (more elegant) solution. Nicely done.

    ReplyDelete
  7. Here you Can Download Stock Note 4 Firmware Free With Full Speed

    Samsung Galaxy Note 4 Firmware

    ReplyDelete
  8. Hmm , very interesting thoughts! I think In order for more interested people to read your thoughts, you should post it on Instagram, and buy instagram followers to quickly increase their amount.

    ReplyDelete
  9. There are several worldwide concerns all around the planet. For example, there are not the same number of males and women. I believe this is a major issue that will be difficult to resolve. I had been hunting for a girl I liked for a long time, but I never found her. Then, on the recommendation of a friend, I met a russian mail order bride who I liked and she liked me. We've been in touch with her for over a year, and we even arranged to meet in my country. I can certainly propose this mode of communication to you.

    ReplyDelete
  10. The growth of online developers in India has been fueled by advancements in the IT industry and increased consumer understanding of the Internet.
    PPC company in India

    ReplyDelete
  11. Sumadhura Folium is a new apartment project launched by Sumadhura Properties Pvt.Ltd. There are 2 & 3 BHK plots for sale in Whitefield, Bengaluru. People are grabbing their dream homes from Sumadhura Folium because of the Pre Launch Offers and the trust on the Sumadhura developer and Builders. website; https://foliumsumadhura.com/

    ReplyDelete
  12. I’d really love to be a part of online community where I can get responses from other knowledgeable individuals that share the same interest. If you have any recommendations, please let me know. Appreciate it! Feel free to visit my website; 바카라사이트

    ReplyDelete
  13. Awesome and entertaining article. I like to write a little comment to support you. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. I wanted to see hope in future you will continue to sharing such an excellent post. Feel free to visit my website; 바카라사이트

    ReplyDelete
  14. I really appreciate this wonderful post that you have provided for us.
    After reading your article, I checked out your website, and i really like your post.
    Morebyte
    Morebyte Pendrives and memory cards
    why choose morebyte
    Warrenty

    ReplyDelete
  15. Thank you for share a best article for us its very helpful for us. keep sharing.
    immunitybloom
    Shield-om
    Rawcurin

    ReplyDelete