Home > Google Maps > Using Google Maps in your Android Application

Using Google Maps in your Android Application

In order to use Google Maps in an Android application, you need to make sure that the application is properly setup to be able to host a MapView.

Although it only takes a couple of steps to prepare your application for using Google Maps, failing to complete or skipping one of these steps can quickly turn this into an error-prone process.

The goal of this article is to go over the required steps in order to use Google Maps, and to list down the common mistakes that result in errors.

In short, the following needs to happen to enable your application for Google Maps :

  • The Android SDK needs to be setup to support Google Maps.
  • A MapView component needs to be added to your layout, containing a valid Google Maps API key
  • The Activity that will be responsible for showing the map needs to extend from MapActivity
  • The application manifest needs to be setup with the android.permission.INTERNET permission
  • The application manifest needs to be setup with the com.google.android.maps library

Some basic setup is described in the Android Hello Mapview tutorial, but I’ve noted down some addtional items.

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 :

android sdk and adv manager

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

keytool with certificate fingerprint

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<com.google.android.maps.MapView
    android:id="@+id/mapview1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:enabled="true"
    android:clickable="true"
    android:apiKey="USE YOUR API KEY HERE" />
</LinearLayout>

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.

package com.ecs.android.sample.mapoverlay;

import android.os.Bundle;

import com.google.android.maps.MapActivity;

public class AndroidMapOverlaySample extends MapActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}
}

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 :

logcat error

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

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.ecs.android.sample.mapoverlay"
      android:versionCode="1"
      android:versionName="1.0">
	<uses-permission android:name="android.permission.INTERNET"/>

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".AndroidMapOverlaySample" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
		<uses-library android:name="com.google.android.maps" />
    </application>
</manifest>

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)

Wrong layout inflated, or invalid reference to the MapView component
Assuming your MapActivity contains code like this :

setContentView(R.layout.main);
mapView = (MapView) findViewById(R.id.mapview1);

Double check that the layout you’re inflating (main.xml in this case), contains a MapView component with id mapview1, like the snippet below :

<com.google.android.maps.MapView
    android:id="@+id/mapview1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:enabled="true"
    android:clickable="true"
    android:apiKey="your api key here" />

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.

Bookmark and Share
Categories: Google Maps Tags: ,
  1. Kaspar
    February 2nd, 2011 at 15:57 | #1

    @ddewaele:
    Hey, I wondered if you ever solved the problem you stated on:
    http://stackoverflow.com/questions/4319369/integrate-a-search-maps-function-in-an-android-app

    I also want to add an auto-complete address search bar, like the one used in Google Maps, in my application and can’t find any examples yet.

    • admin
      February 4th, 2011 at 18:36 | #2

      As a matter of fact I have… I’ll be posting the complete solution and source code here tomorrow… But first gonna enjoy a computer-free environment tonight….

  2. josh
    April 10th, 2011 at 21:37 | #3

    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!

  3. Or
    April 29th, 2011 at 11:56 | #4

    @admin
    Hey,

    I’m also interested in implementing an auto complete address search bar. Could you post your solution at some stage?

    Cheers,
    Or

  4. MJ
    June 14th, 2011 at 16:04 | #5

    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?

    Thanks!
    MJ

  5. GR
    July 16th, 2011 at 00:31 | #6

    Hey does anyone know how to do this with c++?

  6. Rikki
    July 21st, 2011 at 10:50 | #7

    admin :As a matter of fact I have… I’ll be posting the complete solution and source code here tomorrow… But first gonna enjoy a computer-free environment tonight….

    I was searching for some code for that matter but couldn’t find one. Can you share the link. I am able to see only grids on my sample google maps application after applying all your steps.

  7. September 14th, 2011 at 05:51 | #8

    Nice tutorial it helps me a lot ….thanks

  8. Rafael
    September 19th, 2011 at 18:55 | #9

    Great tips!
    Thanks

  9. October 6th, 2011 at 18:25 | #10

    Hi,
    Thank you for great example.

  10. diya
    October 19th, 2011 at 14:00 | #11

    i generate the fingerprints but when i put it on the ” http://code.google.com/android/maps-api-signup.html ” and generate key it gives error that your fingerprints are not valid. please someone help me how i solve this error?

  11. Nurbek
    December 12th, 2011 at 13:10 | #12

    hi , good article but i wanted to add something,
    Multiple maps.jar libraries are references in your project

    when dealing with this error , deleting extra maps.jar ( if there any) from libraries is not enough, from Java Build Path, from Order and Export tab you should tick google also

  12. Pradeep
    February 1st, 2012 at 11:00 | #13

    Too good :) I HAD done the common mistake of placing the uses-library outside of the application tag and hadnt realized it until I saw this blog! Thanks.

  13. LiberiFatali
    February 21st, 2012 at 09:55 | #14

    Thank you. It helps :)

  14. Shilna
    March 15th, 2012 at 23:29 | #15

    Hey Thanks…..It was Quite Helpful! :)

  15. March 17th, 2012 at 10:14 | #16

    I followed your tutorial and I placed user-library between the applications tags but I still got the following error:
    W/dalvikvm(294): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
    E/AndroidRuntime(294): Uncaught handler: thread main exiting due to uncaught exception
    E/AndroidRuntime(294): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{nl.bs.agm/nl.bs.agm.AndroidMapOverlaySample}: java.lang.ClassNotFoundException: nl.bs.agm.AndroidMapOverlaySample in loader dalvik.system.PathClassLoader@43d02ce8
    E/AndroidRuntime(294): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)
    E/AndroidRuntime(294): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
    E/AndroidRuntime(294): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
    E/AndroidRuntime(294): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
    E/AndroidRuntime(294): at android.os.Handler.dispatchMessage(Handler.java:99)
    E/AndroidRuntime(294): at android.os.Looper.loop(Looper.java:123)
    E/AndroidRuntime(294): at android.app.ActivityThread.main(ActivityThread.java:4363)
    E/AndroidRuntime(294): at java.lang.reflect.Method.invokeNative(Native Method)
    E/AndroidRuntime(294): at java.lang.reflect.Method.invoke(Method.java:521)
    E/AndroidRuntime(294): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
    E/AndroidRuntime(294): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
    E/AndroidRuntime(294): at dalvik.system.NativeStart.main(Native Method)
    E/AndroidRuntime(294): Caused by: java.lang.ClassNotFoundException: nl.bs.agm.AndroidMapOverlaySample in loader dalvik.system.PathClassLoader@43d02ce8
    E/AndroidRuntime(294): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
    E/AndroidRuntime(294): at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
    E/AndroidRuntime(294): at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
    E/AndroidRuntime(294): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
    E/AndroidRuntime(294): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2409)
    E/AndroidRuntime(294): … 11 more

    Hopefully you can and will help me ! Thanks in advantage

  16. April 4th, 2012 at 09:07 | #17

    thanks , only your solution worked for me :)

  17. Pepej
    April 17th, 2012 at 07:04 | #18

    did you find any example for autocomplete google maps search??@Kaspar

  18. Giancarlo Leonio
    March 11th, 2013 at 22:36 | #19

    Thanks for the tutorial! Your solution worked for me. I compiled a list of some top tutorials for adding a MapView to an Android Application. I included your post. Check it out/ feel free to share. http://www.verious.com/board/Giancarlo-Leonio/adding-a-map-view-to-an-android-application/ Hope other developers find this useful too. :)

  19. Vairavan Srinivasan
    March 21st, 2013 at 03:35 | #20

    Do you know if this still holds true for API level 17? I installed Google APIs for 17, but i’m not able to create an AVD with that as a target.

  20. sagar
    March 21st, 2013 at 15:57 | #21

    how to get default view of google maps in my emulator…like all the geo points and acting like google maps…can u tell me the solution and its possibility..if yes then how its possible..?

  1. September 5th, 2011 at 22:37 | #1