Download

Google provides a MapView control, which is essentially a touch-sensitive Google Maps UI. Actually getting it working, however, was the source of much angst and frustration. A Google search will yield a number of equally frustrated novice programmers.

There are a number of prerequisites:

  1. You must generate a key to cryptographically sign your application. This proves that the application came from a specific developer. Unsigned applications will not run on actual hardware, although anyone can sign an application on their own.
  2. You have to get a Google Maps API key. This is generated from and unique to the key you sign your application with. Without this API key, the MapView will simply laugh at you and display gray tiles.
  3. You must ask for “Internet” and “Fine Location” permissions in your manifest. Without them, you will not have access to Google Maps (the maps and tiles are downloaded from the internet on-demand) or the user’s current location.

The Hello, MapView tutorial from Google’s site completely neglects to mention the need for #1 and #2, without which the application will not work. An API key for Android, along with instructions to sign your program, can be found here.

After your application is signed and talking to Google Maps, the rest of the code is fairly simple. The XML layout “main” looks 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"
    >
 
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/myLocationText" android:text="Finding location..."></TextView>
    <com.google.android.maps.MapView
    	android:id="@+id/map_view"
    	android:layout_width="fill_parent"
    	android:layout_height="fill_parent"
    	android:enabled="true"
    	android:clickable="true"
    	android:apiKey="whargharbl - get your own"
    />
 
</LinearLayout>

This gives us a small TextView containing latitude and longitude from the previous example with the MapView control filling the rest of the screen.

Programming it is fairly simple. We derive our application’s main activity from MapActivity instead of Activity (MapActivity is itself derived from Activity). This greatly simplifies development, although I was not able to take this shortcut with my tour application proper – I needed it to cooperate with other activities.

public class MyMapActivity extends MapActivity {

Our MapActivity has two main components – a MapView representing the Google Maps interface the user sees and interacts with, and a MapController helper class for programmatically controlling the MapView.

private MapView mapView;
private MapController mapController;

We override the onCreate method like before and use it to configure our MapView and MapController:

 @Override
    public void onCreate(Bundle savedInstanceState) {
        //Call base method
    	super.onCreate(savedInstanceState);
 
    	//"Inflate" our layout
    	setContentView(R.layout.main);
 
    	//Get a handle to our MapView control; store it.
    	mapView = (MapView) findViewById(R.id.map_view);
 
    	//Get the MapView's associated controller.
    	//Believe it or not, used for controlling the MapView
    	mapController = mapView.getController();
 
    	//Set the zoom/display/visible controls of our MapView
    	mapView.setSatellite(true);		//False gets regular map tiles
    	mapView.setStreetView(true);
    	mapView.setBuiltInZoomControls(true);
    	mapView.displayZoomControls(true);
    	mapController.setZoom(17);

This is pretty self-explanatory – we get to configure what UI elements are available on the MapView, such as zoom in/zoom out controls. We also get to pick whether we want satellite imagery or regular, flat map tiles. We then use the MapController to set a sane starting zoom level.

Next, we place an Overlay on top of the MapView. Overlays are transparent UI elements that cover Views and other controls; in the context of the MapView control, they’re used to place pushpins and annotations over a map and to intercept touches. Overlays have z-order – you can place one on top of the other, and touch events filter top-down until something elects to handle it.

    	//Overlays are graphical layers drawn over the map control
    	//Add the built-in "You Are Here" overlay that puts a dot at your current location
    	List<Overlay> overlays = mapView.getOverlays();
    	MyLocationOverlay myLocationOverlay = new MyLocationOverlay(this, mapView);
    	overlays.add(myLocationOverlay);
 
    	//Turn on the compass and the You Are Here dot
    	myLocationOverlay.enableCompass();
    	myLocationOverlay.enableMyLocation();

I omitted the code for hooking up the GPS – it’s identical to the previous GPS example and included in the Workspace download at the top of this post.