Logo Icon Logo
A Crowd-sourced Cookbook on Writing Great Android® Apps
GitHub logo Twitter logo OReilly Book Cover Art

Draw your current location on a Google MapView

Author: Johan Pelgrim
Published? false -- FormatLanguage: W

Problem:

You want to draw your current location on a Google MapView and want to update the location marker on the MapView when the location changes.

Solution:

Use the MyLocationOverlay class from the Google Maps API

Discussion:

Warning The Google Maps V1 API is deprecated; new code should use the V2 API discussed in Recipes 4285 and 4297.

When you want to draw a location marker on a Google MapView you can register for location updates for the network- and or GPS location providers and implement all the necessary callback handlers as is described in recipe Getting Location Information. You can then create a single Overlay as was described in Draw a location marker on a Google MapView or use an OverlayItem which constantly creates new overlays for the new location. Once you get the hang of this it will become a standard tool in your Android toolbox. You can probably create a small utility or library project for this and start reusing that code in various projects.

Fortunately the Google team has already done the hard work and provides all this functionality in the MyLocationOverlay class. The only thing you have to do is add this overlay to your MapView's overlay and start listening for location changes by calling the enableMyLocation() method on your instance of MyLocationOverlay in your Activities onResume() method. Typically you should call disableMyLocation() in your onPause() activity lifecycle callback method to stop listening for location changes.

The code

Again, use the check-list from the Getting ready for Google Maps development recipe to prepare a skeleton Google Maps project.

public class MainActivity extends MapActivity {
    
    private MyLocationOverlay mMyLocationOverlay;
    private MapController mMapController;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        MapView mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);
        mapView.setSatellite(true);

        mMyLocationOverlay = new MyLocationOverlay(this, mapView);

        mapView.getOverlays().add(mMyLocationOverlay);
        mapView.postInvalidate();

        mMapController = mapView.getController();
        mMapController.setZoom(19);

    }

    @Override
    protected void onResume() {
        super.onResume();
        mMyLocationOverlay.enableMyLocation();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mMyLocationOverlay.disableMyLocation();
    }

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

Note: Make sure your Android Virtual Device has GPS support!

When you start your android project you will get an empty MapView screen. That is, no location marker is drawn. The MyLocationOverlay class has a method runOnFirstFix(Runnable runnable) which tries to get a location as quickly as possible, using whatever method, set it on the MyLocationOverlay instance and execute your run-method. To run some code on the first geo fix we add something like the code below, right under the mMyLocationOverlay object creation:

        mMyLocationOverlay.runOnFirstFix(new Runnable() {
            @Override
            public void run() {
                mMapController.animateTo(mMyLocationOverlay.getMyLocation());
            }
        });

Take your app for a spin and set a geo fix by telnetting to your AVD on port 5554 (default emulator port) and run a "geo fix <longitude> <latitude>" command, e.g. "geo fix -74.044688 40.689091".

Note: Once you start your AVD you will see the process ID in the window title. This also corresponds to the telnet port you can connect to. When you have to AVDs up and running you can use this same number to place calls and send text messages to each other.

You can do a lot with the telnet interface, but that is beyond the scope of this recipe. Type help to see a list of commands. Type help <command> to see help about a specific command, e.g. help geo will give you a list of commands you can use to manipulate your AVD's location, i.e. geo fix and geo nmea. Typing help geo fix will give you specific help about the geo fix command options, etc.

When you change the location you will notice that the MapView will nicely follow along as long as you make small steps. When the location marker gets near the border of your MapView it nicely recenters your MapView to the current location. However, when your steps are larger or your location becomes stale you will no longer see updates. This is probably not what you want. You can handle this by extending the MyLocationOverlay class and implementing the onLocationChanged(Location location) method like this (we use an inner type).

    private class MyLocationOverlayExtension extends MyLocationOverlay {

        public MyLocationOverlayExtension(Context context, MapView mapView) {
            super(context, mapView);
        }
        
        @Override
        public synchronized void onLocationChanged(Location location) {
            super.onLocationChanged(location);
            GeoPoint point = new GeoPoint((int) (location.getLatitude() * 1E6), (int) (location.getLongitude() * 1E6));
            mMapController.animateTo(point);
        }
        
    }

Now let your overlay instance extend from MyLocationOverlayExtension and fire up your Android application again.

Note: You can also listen for compass changes and display a compass rose with an MyLocationOverlay. However, there is no standard compass support in the emulator. If you need to use the compass or other sensors in your project look at the SensorSimulator project at http://openintents.org

See Also:

Getting Location Information Getting ready for Google Maps development Draw a location marker on a Google MapView http://code.google.com/android/add-ons/google-apis/reference/com/google/android/maps/MyLocationOverlay.html

Download:

The source code for this project can be downloaded from https://github.com/downloads/jpelgrim/androidcookbook/MyLocationOverlayExample.zip.
No records found.