Setting up our Android SDK for Google Maps.

If you want to do anything with Google Maps, you’ll need to ensure that your Android SDK has the necessary components installed. A key component is called the Google APIs Add-on, as according to Google :

is an extension to the Android SDK development environment that lets you develop applications for devices that include Google’s set of custom applications, libraries, and services. A central feature of the add-on is the Maps external library, which lets you add powerful mapping capabilities to your Android application.

More information on how to install the Google APIs Add-on can be found here. After the installation, you should see the Google APIs in your installed packages :

Setting up our project for Google Maps.

Now that we have setup your Android SDK with the Google APIs, you can create Android Projects in Eclipse that target these Google APIs. This is required in order to be able to use the classes residing in the maps.jar file (classes like MapActivity).

After your project has been created, you should see the following in your project explorer :

Retrieve a Google Maps API Key

Before we can start using maps in our Android application, you need to obtain a Maps API Key.
Signing up for such an API key is fairly straightforward, and requires you to do the following :

Registering the MD5 fingerprint of the certificate that you will use to sign your application. The Maps registration service then provides you a Maps API Key that is associated with your application’s signer certificate.

Adding a reference to the Maps API Key in each MapView, whether declared in XML or instantiated directly from code. You can use the same Maps API Key for any MapView in any Android application, provided that the application is signed with the certificate whose fingerprint you registered with the service.

More information on getting a MapKey for development purposes can be found here.

You’ll need to run a command line tool called keytool to display the certificate fingerprint. The keytool command is distributed with any Java JDK / JRE and can be located under %JAVA_HOME%/bin

Once we have the API key, we can add our MapView component in the main layout like this :

Important : Your API key is linked to the Android SDK keystore you’re currently using. This means that if you run your application on another development environment, where a different Android SDK keystore is installed, the API key will not work, and you won’t see any tiles being loaded on the Map.

Extending from MapActivity

The Activity that will inflate this layout needs to extend from MapActivity instead of the usual Activity base class.

As you can see, because we’re deriving from the MapActivity class, our activity needs to implement the isRouteDisplayed method. We’ll just have it return false as we’re not interested in showing route information. Having your Activity extend from MapActivity will avoid errors like the one below :

Always keep an eye out on your logcat.

Configuring the application manifest

As can be seen in the manifest below, we’ve added the android.permission.INTERNET permission, and the com.google.android.maps library

Note that the use-library element is a child of the application element. Android won’t flag the manifest with an error if the uses-library is placed outside the application, and it’s a mistake that is often made.

Setting up our emulator for Google Maps.

If you want to test your application through the emulator, you’ll need to have an AVD (Android Virtual Device) that has includes the Google APIs Add-On. Before you will be able to create such an AVD, you need to ensure that you’ve installed the Google APIs Add-On.

When creating an emulator, make sure it has the proper target defined. The target should be called something like Google APIs (Google Inc).

Common mistakes

To conclude, I’ve added some common mistakes that people are making, and some common errors that people are getting while working with Google Maps in their Android applications.

user-library is not placed inside the application tags
When the google maps library is put outside of the application tag, Android doesn’t flag it as an error, and the application starts but throws an exception :

WARN/dalvikvm(214): Link of class 'Lcom/ecs/android/sample/mapoverlay/AndroidMapOverlaySample;' failed
DEBUG/AndroidRuntime(214): Shutting down VM
WARN/dalvikvm(214): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
ERROR/AndroidRuntime(214): Uncaught handler: thread main exiting due to uncaught exception
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.ecs.android.sample.mapoverlay/com.ecs.android.sample.mapoverlay.AndroidMapOverlaySample}: java.lang.ClassNotFoundException: com.ecs.android.sample.mapoverlay.AndroidMapOverlaySample in loader dalvik.system.PathClassLoader@44e83b20
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
at android.app.ActivityThread.access$2200(ActivityThread.java:119)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4363)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: com.ecs.android.sample.mapoverlay.AndroidMapOverlaySample in loader dalvik.system.PathClassLoader@44e83b20
at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2409)
... 11 more

Solution for this is to make sure that the following line

<uses-library android:name="com.google.android.maps" />

is placed within the application tags.

Activity is not extending MapActivity
When the Activity that is inflating the MapView is not extending from MapActivity, you’ll get the following exception :

Caused by: java.lang.IllegalArgumentException: MapViews can only be created inside instances of MapActivity.
at com.google.android.maps.MapView.(MapView.java:281)
at com.google.android.maps.MapView.(MapView.java:254)

When the Activity that is inflating the MapView is not extending from MapActivity AND the maps library is placed outside the application tag, you can get the following exception :

Caused by: java.lang.ClassNotFoundException: com.google.android.maps.MapView in loader dalvik.system.PathClassLoader@44bfdb20
at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
at android.view.LayoutInflater.createView(LayoutInflater.java:466)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:565)
... 20 more

No internet permission is granted
When the map displays, but no map tiles are loaded, check if you granted internet permission and provided a valid API key was configured for the MapView component in the layout.

No valid API key is provided.
What’s important to note here is that your API key is linked to the Android SDK keystore you’re currently using. This means that if you run your application on another development environment, where a different Android SDK keystore is installed, the API key will not work, and you won’t see any tiles being loaded on the Map.

Multiple maps.jar libraries are references in your project
Another error can occur when your project has multiple references to the maps.jar library. In those cases, the following error will occur :

Uncaught handler: thread main exiting due to uncaught exception
java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
at dalvik.system.DexFile.defineClass(Native Method)
at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:209)
at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:203)
at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2409)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
at android.app.ActivityThread.access$2200(ActivityThread.java:119)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4363)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
at dalvik.system.NativeStart.main(Native Method)

Conclusion

Integrating Google Maps in an Android app is pretty straightforward but some common mistakes can be made. Hopefully this article will help you avoid these mistakes, and get you up & running with Google Maps in no time.

Hey I really need help with mine, I have tried a million times putting it into a Tab, I have looked everywhere, but I think you will be able to spot my error, as I can’t see it, some of the errors you have displayed say some things in the manifest are not there, but they are. And the error is cannot inflate the com.google.android.maps.MapView along with classnotfound exception. Manifest is fine, just the tab class does inherit the MapActivity class too, I really don’t know what it is!

Hi. I’d like to create an app that allows users to find relevant businesses using this tool and then also leave reviews about their experiences at those places so future users can also benefit.
How can I do that?