Location Based Services on Android – Part 2/3 – ItemizedOverlay
This is the second part of my blog series about how to use location based services in Google Android.
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 2 – Google Maps and ItemizedOverlay
In this part we will integrate an ItemizedOverlay to a Google Map view in Android. Whenever a new location is received with the GPS sensor we will capture that location, move the map to this position and show an icon.
You should already have integrated a google map. If you do not know how to do this – read the first part of this series. You can use the application of the first part of this series as base.
First I will provide the needed source code. I will not explain every single line of code, but explain the important steps.
To use a Google Maps View with an ItemizedOverlay we need an Activity and a class overwriting Itemized Overlay.
- Activity: LocationBasedServicesV2
- Overlay: MyItemizedOverlay
The activity
package de.itemis.frey.blog.lbsv2; import java.util.Iterator; import java.util.List; import android.content.Context; import android.graphics.drawable.Drawable; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.view.View; import android.widget.LinearLayout; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; import com.google.android.maps.OverlayItem; /** * This application demonstrates the use of the google maps view in combination * with an ItemizedOverlay. * * @author frey */ public class LocationBasedServicesV2 extends MapActivity { private MapView myMap; private LocationManager locManager; private LocationListener locListener; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); initMap(); initLocationManager(); } /** * 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); } /** * Initialise the location manager. */ private void initLocationManager() { locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); locListener = new LocationListener() { public void onLocationChanged(Location newLocation) { createAndShowMyItemizedOverlay(newLocation); } public void onProviderDisabled(String arg0) { } public void onProviderEnabled(String arg0) { } public void onStatusChanged(String arg0, int arg1, Bundle arg2) { } }; locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener); } /** * This method will bea called whenever a cahnge of the current position * is submitted via the GPS. * @param newLocation */ protected void createAndShowMyItemizedOverlay(Location newLocation) { List overlays = myMap.getOverlays(); // first remove old overlay if (overlays.size() > 0) { for (Iterator iterator = overlays.iterator(); iterator.hasNext();) { iterator.next(); iterator.remove(); } } // transform the location to a geopoint GeoPoint geopoint = new GeoPoint( (int) (newLocation.getLatitude() * 1E6), (int) (newLocation .getLongitude() * 1E6)); // initialize icon Drawable icon = getResources().getDrawable(R.drawable.pointer); icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon .getIntrinsicHeight()); // create my overlay and show it MyItemizedOverlay overlay = new MyItemizedOverlay(icon); OverlayItem item = new OverlayItem(geopoint, "My Location", null); overlay.addItem(item); myMap.getOverlays().add(overlay); // move to location myMap.getController().animateTo(geopoint); // redraw map myMap.postInvalidate(); } @Override protected boolean isRouteDisplayed() { return false; } }
MyItemizedOverlay
package de.itemis.frey.blog.lbsv2; import java.util.ArrayList; import java.util.List; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import com.google.android.maps.ItemizedOverlay; import com.google.android.maps.MapView; import com.google.android.maps.OverlayItem; public class MyItemizedOverlay extends ItemizedOverlay { private List items; private Drawable marker; public MyItemizedOverlay(Drawable defaultMarker) { super(defaultMarker); items = new ArrayList(); marker = defaultMarker; } @Override protected OverlayItem createItem(int index) { return (OverlayItem)items.get(index); } @Override public int size() { return items.size(); } /* * (non-Javadoc) * * @see * com.google.android.maps.ItemizedOverlay#draw(android.graphics.Canvas, * com.google.android.maps.MapView, boolean) */ @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { super.draw(canvas, mapView, shadow); boundCenterBottom(marker); } public void addItem(OverlayItem item) { items.add(item); populate(); } }
Receive location changes from the gps sensor
After starting the application and initialising the map (initMap()), we initialize a LocationManager (initLocationManager()). A LocationManager provides capabilities to receive information from the GPS sensor.
To get informed about position changes we need an instance of a LocationListener and bind it to the LocationManager. Its only necessary to implent the method onLocationChanged(), when the location changes we call the method createAndShowMyItemizedOverlay() and submit the new location as parameter.
Create the ItemizedOverlay and add it to the map
Whenever a new position is received from the GPS sensor the method createAndShowMyItemizedOverlay() is called. Inside this method we want to create an Overlay containing an icon showing the current position on the map. The method does many things which should be splitted in several methods in a productive environment – i leave them in this single method to keep things small and avoid source code-”jumps”.
First we remove previously added overlays from the map if necessary and transform the received Location to a GeoPoint, which is better supported by the Google Maps API.
Next we create the icon we want to use as marker for the position. The icon is an image “pointer.png” which is stored in the folder “res/drawable”. We create an instance of the MyitemizedOverlay and pass the created icon as paramter.
Now we use the geopoint to create an OverlayItem and add it to the Overlay. After adding the MyItemizedOverlay we animate the map to the position.
postInvalidate() is used to inform the map to redraw itself.
MyItemizedOverlay
To use ItemizedOverlays you have to extend the class ItemizedOverlay. You have to overwrite the methods createItem(), size() and create the constructor with marker as parameter. All methods are pretty simple and need no further explanation.
In addition i used the methods addItem() and draw().
The method populate() in addItem() is used to start the processing the ItemizedOverlay, it should be called as soon as data is available.
In the draw()-method, we call boundCenterBottom() to inform the ItemizedOverlay about the orientation of our overlay.
Testing the application
For testing of the application use the DDMS capabilites of your eclipse – or the connect vie telnet to the Android console and use the “geo fix” command as described in the first part of this series.
You are welcome to post comments or suggestions for improvement.
The complete series:

Thursday, 16. April 2009 15:30
Great tutorial, thank you! I have just a few comments for changes I have on the source code:
You: if (overlays.size() > 0) {
I: if (overlays.size() > 0) {
you: Drawable icon = getResources().getDrawable(R.drawable.pointer);
I: Drawable icon = getResources().getDrawable(R.drawable.icon);
you: protected OverlayItem createItem(int index) {return items.get(index);}
I: protected OverlayItem createItem(int index) {return (OverlayItem) items.get(index); }
Again, thank you for this nice introduction to Google Maps
Friday, 17. April 2009 8:51
Hello Konrad,
thank you for your comment.
- I used my own Icon as marker on the map.
- The method createItem is changed now.
Tuesday, 2. June 2009 13:49
Andreas,
I have followed your tutorial exactly (except for a few variable names). I was using the Android android icon like in http://developer.android.com/guide/tutorials/views/hello-mapview.html
However, when I run the application, it keeps showing the icon from the previous tutorial (with the flashing blue dot). Any ideas??
Wednesday, 3. June 2009 16:32
…in addition to my previous post:
never mind the icon, got that sorted out. However, I have another severe problem now:
I can only provide a location twice, either through DDMS or telnet. The onStatusChanged method returns gps as available. The icon shows up when I send the first location, moves when I send the second location. When I send a location for the third time, nothing happens. The onLocationChanged method isn’t called, neither are any other locationListener methods – gps isn’t reported to be unavailable or anything. MapActivity reports an error as soon as our Activity is started, saying “Couldn’t get connection factory client”.
Wednesday, 3. June 2009 18:56
Hello Lex,
This is a bug of the emulator. Look here for details: http://groups.google.com/group/android-developers/browse_frm/thread/3f4c9d83ddcf5815/3dcd5c81abb3752b
Monday, 24. August 2009 13:10
I don’t know but there’s smt wrong with this line
if (overlays.size() > 0)
In my eclipse, it said that “gt can not be resolved”
Please help me
(
Monday, 24. August 2009 15:52
Oh my god, that’s “>”. I don’t know how but thanks for your tutorial
OMG!!! There’s nothing displays on my map except the map. There’s no icon (although I added an icon into drawable folder) on my map
Thursday, 8. October 2009 0:58
Is there anything else in res/drawable/ aside from the PNG file? Did you have to reference the PNG file from another of the res/ XML files at all?
Thursday, 8. October 2009 9:04
In the res/drawable there must be a file named “pointer.png”. That is all. No there is no more reference – the reference to this file comes from the generated R.java.