Location Based Services on Android – Part 1/3 – MyLocationOverlay
A juicy feature of Android is its capability for location based services. The combination of the integrated GPS-Device with the easy use of Google Maps allows powerful location based applications.
Anyway, the first use of these technologies contains some hazards. Therefore, I decided to write some blog entries explaining the first steps with Android and Google Maps.
The first part of this series describes the integration of the google map view and the use of the MyLocationOverlay. In the second part I demonstrate how to use an ItemizedOverlay on a google map. Third and last part of this series describes how to build a custom Overlay and show it on the map.
- Part 1 – Enable Google Maps and use a MyLocationOverlay
- Part 2 – Google Maps and ItemizedOverlay
- Part 3 – Google Maps and CustomOverlays
Part 1 – Enable Google Maps and use a MyLocationOverlay
The first part of this series contains a short description how to integrate Google Maps in an Android application and show the current location using the MyLocationOverlay.
In order to follow these steps, you should already have installed the android sdk Eclipse as IDE and created a new Android project. If you have not done this so far, look at the Android Documentation.
Integrate Google Maps in your application
We start by editing the layout definition file of the application. The following snippet shows the content of the /res/layout/main.xml file. Its contents are described below.
<RelativeLayout 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 xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" android:enabled="true" android:id="@+id/mymap" android:apiKey="@string/mapskey" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/myzoom" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" /> </RelativeLayout>
This layout definition contains a little we trick we use to position the zoom-controls at the bottom of the map. We use a RelativeLayout, which uses the whole viewport as container. This contains the Google Maps View (com.google.android.maps.MapView) and a LinearLayout. The LinearLayout will contain the Zoom-Controls of the map. Inside a RelativeLayout, Views can be positioned in relation to each other or in relation to its parent (the RelativeLayout). The map simply uses the complete viewport. For the LinearLayout (with the zoom controls) we use the abilities of the RelativeLayout and position it centered at the bottom of the RelativeLayout, above the map.
NOTE: For sdk 1.5 it is not needed anymore to work with this trick. But it still works.
The IDs of the LinearLayout and the map are used to make the Views accessible inside the Activity.
To use the Google Maps View an API key is needed, this will be stored as string ressource referenced by the key @string/mapskey.
Get an Google Maps API key
Android only allows the installation of signed applications. Before installing an application on the emulator, Eclipse will automatically sign the application, using a debug certificate which comes along with the Android sdk. The google maps api key is based on the certificate used to sign the application. Detailed descriptions about signing an application can be found in the online documentation.
To obtain a google maps api key (using the debug certificate) you have to do the following steps:
- Create a md5 checksum of the debug certificate
Find the debug.keystore- Windows Vista: C:\Users\’user’\.android\debug.keystore
- Windows XP: C:\Documents and Settings\’user’\.android\debug.keystore
- Mac OS X und Linux: ~/.android/debug.keystore
and call the command
keytool -list -alias androiddebugkey -keystore .keystore -storepass android -keypass android
The md5 checksum is generated and printed to the screen. - Register the md5 checksum
Register the generated checksum at Maps API key. A google account is required to do so. - Edit ressources
Paste the Maps API key to the resources.
The /res/strings.xml with the Maps key of my debug certificate
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">LocationBasedServicesV1</string> <string name="mapskey">0zHDFEa6rhx5Je8xqLmDaH6kEym5ga9nxV49H5w</string> </resources>
A detailed description how to generate the Google Maps API key for Android can be found in the reference.
Add required permissions and libraries to the manifest
The application requires 2 permissions.
- Google maps requires access to the internet (android.permission.INTERNET)
- MyLocationOverlay requires access to the GPS (android.permission.ACCESS_FINE_LOCATION)
In addition, the library Google Maps API (com.google.android.maps) must be included to the project.
The AndroidManifest.xml containing all necessary changes:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.itemis.frey.blog.lbsv1" android:versionCode="100" android:versionName="1.0.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".LocationBasedServicesV1" 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> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> </manifest>
Add MyLocationOverlay to the map and init the zoomcontrols
The activity calls in its onCreate Method the two methods initMap and initMylocation.
- initMap
This method initialises the zoom controls of the map and adds them to the LinearLayout. - initMyLocation
- Instantiate a new MyLocationOverlay
- Enable the MyLocationOverlay
- Add the overlay to the list of overlays of the map
The LocationBasedServicesV1.java
package de.itemis.frey.blog.lbsv1; import android.os.Bundle; import android.view.View; import android.widget.LinearLayout; import com.google.android.maps.MapActivity; import com.google.android.maps.MapView; import com.google.android.maps.MyLocationOverlay; /** * This application demonstrates the use of the google maps view in combination * with a MyLocationOverlay. * * @author frey */ public class LocationBasedServicesV1 extends MapActivity { private MapView myMap; private MyLocationOverlay myLocOverlay; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); initMap(); initMyLocation(); } /** * Initialise the map and adds the zoomcontrols to the LinearLayout. */ private void initMap() { myMap = (MapView) findViewById(R.id.mymap); View zoomView = myMap.getZoomControls(); LinearLayout myzoom = (LinearLayout) findViewById(R.id.myzoom); myzoom.addView(zoomView); myMap.displayZoomControls(true); } /** * Initialises the MyLocationOverlay and adds it to the overlays of the map */ private void initMyLocation() { myLocOverlay = new MyLocationOverlay(this, myMap); myLocOverlay.enableMyLocation(); myMap.getOverlays().add(myLocOverlay); } @Override protected boolean isRouteDisplayed() { return false; } }
The application is now ready to receive gps signals and show them using a MyLocationOverlay.
Trigger the “GPS” of the emulator
It is possible to test the application and the gps device using the emulator. First, start the application (run as android applicaition). The easiest way to emulate incoming gps signals, is by using the “DDMS” Perspective in Eclipse. There you can send Locations via the Emulator control.
However this is not possible with a german operating system. Due to a bug in android concerning the different localised date format. But you can use telnet to connect to the emulator console and send a new position to the emulator.
- open a terminal
- type “telnet localhost 5554″ – you should now be connected to the emulator
- send the geo fix command, for example “geo fix 9 49“
The application should now show a pin at the given location. Whenever you change the position, the maps should center to this new coordinate. (This only works, when the pin was already visible before).
So that’s it. In the next part of this series, i will explain how to use a Google Map with ItemizedOverlays.
You are welcome to post comments or suggestions for improvement.
The complete series:

Monday, 6. April 2009 11:50
Hi,
great tutorial, thanks!
Do you know how to add the zoom controls to an image view, do you always have to have a mapview present to obtain them from?
Thanks
Monday, 6. April 2009 12:01
Hi Paul,
no, you dont need to use the built-in zoomcontrols. You can also use image-buttons oder image-views to control the zooming of the map.
To do so, simply use 2 ImageButtons, one for “+”, one for “-” zoom
<RelativeLayout ... > <com.google.android.maps.MapView ... android:id="@+id/map" /> <ImageButton android:id="@+id/buttonPlus" android:src="@drawable/plus" android:layout_alignTop="@id/map" android:layout_alignLeft="@id/map" ... /> <ImageButton android:id="@+id/buttonMinus" android:src="@drawable/minus" android:layout_alignTop="@id/map" android:layout_toRightOf="@id/buttonPlus" ... /> </RelativeLayout>When initialising your buttons, simply use the Methods:
to zoom the map by yourself
Monday, 6. April 2009 12:28
Hi, thank you for a speedy response!
I think I did not explain myself well.
What I mean is how do you get to the zoom controls as they appear in the Pictures application?
I have an image displayed which I need to zoom but I do not understand how to get the zoom controls to work with images.
Your code showed me how to place them within a relative layout but I do not know how attach the controls?
Thanks
Monday, 6. April 2009 12:39
Hi Paul,
Do you want to zoom a google map, or do you want to zoom an image?
Monday, 6. April 2009 12:46
Hi,
I want to zoom an image. I see the Android G1 has a Pictures application that allows the user to zoom an image using the zoom controls.
Monday, 6. April 2009 12:50
Hi,
sorry I did not try this yet. When I do i will post about it in this blog.
Unfortunately my next steps are to continue this series.
Friday, 10. April 2009 9:04
Hi,
Thanks for your fabulous tutorial examples!
I re-do your example in my Eclipse step by step, and it can be compled properly. However, I could not run it on Android Emulator, the error message shows that the application has stopped unexpectedly.
I do not know how to fix it and I appreciate your response in advance.
Friday, 10. April 2009 11:14
Hi,
I have got the problem. That is due to my stupid miss “android” between “google” and “maps” in “com.google.android.maps.MapView” in main.xml.
Thank you anyway and hope your more wonderful tutorial about android development.
Wednesday, 15. April 2009 6:34
Hi,
I am able to run the above sample application and get the google map, but when i send the latitude,longitude values from telnet, it doesn’t show the pin at he given location.
Can you help me what might be the problem?
Regards, Edwin
Wednesday, 15. April 2009 8:48
Hi Edwin,
sometimes the map is not positioned automatically to the new position. Try to search it on the map and then resend long/lat values.
In addition check the following things.
- Do you add the overlay to the map?
- Is the permission “android.permission.ACCESS_FINE_LOCATION” set?
- Is there an error in the logcat view?
Thursday, 21. May 2009 11:03
I am not able to add the overlay to map.I get the message application stopped unexpectedly.I get this message when i include these lines :
myLocOverlay.enableMyLocation();
myLocOverlay.enableCompass();
can you please help me fix it?
Saturday, 23. May 2009 11:24
Hi Ann,
I suppose you did not set all needed permissions. You need to set the permission “android.permission.ACCESS_FINE_LOCATION” to access the LocationManager.
Try to verify all permissions, you also should check the LogCat view (Eclipse) and have a lookt at the stacktrace of the thrown exception.
Hope that helps,
Andreas
Sunday, 24. May 2009 9:43
Hi Andreas,
Thanks for the guidance after adding all the permissions i get these errors:
05-24 13:02:47.547: ERROR/vold(538): Error opening switch name path ‘/sys/class/switch/test2′ (No such file or directory)
05-24 13:02:47.547: ERROR/vold(538): Error bootstrapping switch ‘/sys/class/switch/test2′ (m)
05-24 13:02:47.547: ERROR/vold(538): Error opening switch name path ‘/sys/class/switch/test’ (No such file or directory)
05-24 13:02:47.547: ERROR/vold(538): Error bootstrapping switch ‘/sys/class/switch/test’ (m)
05-24 13:02:47.648: ERROR/flash_image(544): can’t find recovery partition
05-24 13:02:57.269: ERROR/MemoryHeapBase(568): error opening /dev/pmem: No such file or directory
05-24 13:02:57.269: ERROR/SurfaceFlinger(568): Couldn’t open /sys/power/wait_for_fb_sleep or /sys/power/wait_for_fb_wake
05-24 13:02:57.298: ERROR/GLLogger(568): couldn’t load library (Cannot find library)
05-24 13:02:57.378: ERROR/GLLogger(568): couldn’t load library (Cannot find library)
05-24 13:02:59.498: ERROR/BatteryService(568): Could not open ‘/sys/class/power_supply/usb/online’
05-24 13:02:59.498: ERROR/BatteryService(568): Could not open ‘/sys/class/power_supply/battery/batt_vol’
05-24 13:02:59.498: ERROR/BatteryService(568): Could not open ‘/sys/class/power_supply/battery/batt_temp’
05-24 13:02:59.758: ERROR/EventHub(568): could not get driver version for /dev/input/mouse0, Not a typewriter
05-24 13:02:59.787: ERROR/System(568): Failure starting core service
05-24 13:02:59.787: ERROR/System(568): java.lang.SecurityException
05-24 13:02:59.787: ERROR/System(568): at android.os.BinderProxy.transact(Native Method)
05-24 13:02:59.787: ERROR/System(568): at android.os.ServiceManagerProxy.addService(ServiceManagerNative.java:146)
05-24 13:02:59.787: ERROR/System(568): at android.os.ServiceManager.addService(ServiceManager.java:72)
05-24 13:02:59.787: ERROR/System(568): at com.android.server.ServerThread.run(SystemServer.java:163)
05-24 13:02:59.787: ERROR/AndroidRuntime(568): Crash logging skipped, no checkin service
05-24 13:02:59.799: ERROR/EventHub(568): could not get driver version for /dev/input/mice, Not a typewriter
05-24 13:03:00.478: ERROR/LockPatternKeyguardView(568): Failed to bind to GLS while checking for account
05-24 13:03:03.307: ERROR/ApplicationContext(568): Couldn’t create directory for SharedPreferences file shared_prefs/wallpaper-hints.xml
05-24 13:03:08.418: ERROR/MediaPlayerService(542): Couldn’t open fd for content://settings/system/notification_sound
05-24 13:03:08.418: ERROR/MediaPlayer(568): Unable to to create media player
05-24 13:03:03.273: ERROR/ActivityThread(608): Failed to find provider info for android.server.checkin
05-24 13:03:04.462: ERROR/ActivityThread(608): Failed to find provider info for android.server.checkin
05-24 13:03:04.542: ERROR/ActivityThread(608): Failed to find provider info for android.server.checkin
05-24 13:03:12.902: ERROR/ActivityThread(728): Failed to find provider info for com.google.settings
05-24 13:03:14.092: ERROR/MapActivity(728): Couldn’t get connection factory client
can you please guide me how to overcome these errors?
Tuesday, 26. May 2009 11:46
Finally a tutorial which is up to date with the latest SDK! I am getting exactly the same error like Ann.
Also, do you know where to find the Google Android Maps API? The link
http://developer.android.com/reference/com/google/android/maps/package-summary.html
which is Google’s first hit is broken!
Tuesday, 26. May 2009 19:39
Hello Ann, Hello Lex,
i adjusted this tutorial for sdk 1.5 now. There was a small issue regarding the zoom-Controls (This works much easier in sdk 1.5 now). I also updated the Paths to the debug.keystores.
You can now simply activate the zoom controls of the google map by using the method:
“theMap.setBuiltInZoomControls(true);”
Feel free to retry the new version of the java file. I would be glad about a response.
Wednesday, 27. May 2009 3:20
hi Andreas,
Thanks.I was able to get expected results.
When i went through google apis on android sdk1.5 many packages have been removed especially navigation(overlay controller,DrivingDirections etc) classes.How can we implement them on android 1.5?
Thursday, 28. May 2009 15:17
Looks like I had a black screen coz I was using myLocOverlay.enableCompass(). I presume I will need it eventually for my navigation application, but that’s out of the scope of this post
Friday, 10. July 2009 7:55
hey…ven i run thid appln i m gettin de error mess,”Could not find MapView.apk!”
how do i solve dis….plz help
Friday, 10. July 2009 9:16
Hello Sany,
you provide not enough information to solve this problem. Seems you have some problems with your SDK itself. Try to reselect the Android Virtual Device (AVD) inside Eclipse and try again.
If this will not work … try to search in the Google Groups …
http://groups.google.com/group/android-beginners/browse_thread/thread/0621da80d4b23f08
Many Greetings,
Andreas
Tuesday, 21. July 2009 7:23
Hi Andreas Frey,
this is tutorial is superb,it is do step by step,
am seeing these 3 versions,how i can approach your
other tutorials..means further tutorail..if u see this comment..please give some suggestion..how i can follow your tutorial..
Monday, 27. July 2009 21:54
Ok, as so often trying is the best way to learn.
I found a solution for my question:
GeoPoint myLoc = new GeoPoint(myLocOverlay.getMyLocation().getLatitudeE6(),
myLocOverlay.getMyLocation().getLongitudeE6());
mapController.animateTo(myLoc);
Thanks again!
Rudi
Monday, 24. August 2009 17:50
However this is not possible with a german operating system. Due to a bug in android concerning the different localised date format. But you can use telnet to connect to the emulator console and send a new position to the emulator.
1. open a terminal
2. type “telnet localhost 5554″ – you should now be connected to the emulator
3. send the geo fix command, for example “geo fix 9 49“
====>>>>> I don’t know how to run it, someone please helps
Thursday, 5. November 2009 2:11
Hi, Thanks for the tutorial but I have got a problem.
I have followed each step precisely but eclipse does not recagnize the google imports. e.g:
import com.google.android.maps.MapActivity;
how can I solve this problem? thanks in advance
Thursday, 5. November 2009 10:02
Please be sure to set the Android Build Target to the version with Google API, not only Android. (->Project properties -> Android)
Thursday, 5. November 2009 15:49
Thank you so much , problem solved .
Thursday, 5. November 2009 18:01
Hi,
another question , I have typed
telnet localhost 5554
and I got a connection refused error,
I either looked through nmap localhost but there wasn’t such an open port and I have tried other open ports but they worked neither?
Thursday, 5. November 2009 21:32
When you start the emulator, the port number it uses should be visible at the title of the emulator-window. Use the telnet command with that port.
Thursday, 7. January 2010 9:14
I have done as u directed. I am getting the grids of the google maps but not getting the maps on my android emulator.I donno if it is Internet problem. But i have set the internet permissions also.I am struggling to solve this problem from past three days.I have project demo on saturday. Could anyone help me on this issue as early as possible
Thursday, 7. January 2010 10:39
An empty grid indicates, you have no valid Google maps API key. Have a look at this: http://code.google.com/intl/de-DE/android/add-ons/google-apis/mapkey.html
Monday, 18. January 2010 17:53
Thx very much!
I had a lot of trouble getting the tutorials on internet running (DMMS didn’t work and I couldn’t find out why) but finally it all comes together by reading your blog. Part 3 also helps to get my first Android application up and running.
Thx again!
Tschüss,
Rob (NL)
Saturday, 27. February 2010 21:37
Good tutorial, wish I’d found it sooner, however on mine there is nothing showing for my location (no pin nor blue dot), also is it possible to change the marker with my own image?
Thanks,
Dez (UK)