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

Using the Google Maps API V2

Author: Ian Darwin -- Published? true -- FormatLanguage: W

Problem:

Now that you've set up your environment as in 4285, you want to do something with the Maps API.

Solution:

This Recipe will show some of the neat things you can do using the Maps API.

Discussion:

There is a wealth of functionality in the GoogleMap class. In this recipe we will show how to:

  • add one or more GoogleMaps-style Markers to the map;
  • move the map to a given location;
  • display the (mandatory!) internationalized attribution text;
  • add some extra UI elements.

The main class through which you generally interact with the map is the GoogleMap class.

Add Markers and Center the Map Position

First, we need to get the GoogleMap controller from the layout, in onCreate(). The MapFragment that we used in the layout file in 4285 has a getMap() method which returns the GoogleMap.

map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

To add markers ("map pins") to the map, create a LatLng object, and call the GoogleMap's addMarker() object. This is a "fluent API", each call returning the object operated upon, supporting what some Java people call "method call chaining", so you can call map.addMarker().setTitle().setSnippet() and so on. The code looks like this:

LatLng location = new LatLng(markerLat, markerLng);
    map.addMarker(new MarkerOptions().position(location)
    .title(markerTitle)
    .snippet(markerSnippet));

The "title" and "snippet" are the title and detail text that pops up when the user taps the map marker.

The code below shows a complete(?) example of creating a map with half a dozen marker pins, taken from data stored in an array. Unsurprisingly this data originally came from Google Map I prepared on the Google Maps web site for a computer conference at the University of Toronto. A better way of getting the data - actually used in the Conference App - is to download the KML file from Google Maps and parse it with an XML Pull Parser (see 2217).

The map can be moved and zoomed to give a convenient starting view. Google Maps API v2 uses the notion of a "camera" or view position, which we set with moveCamera().

// Move the "camera" (view position) to our center point with a zoom of 16.
final LatLng CENTER = new LatLng(lat, lng);
map.moveCamera(CameraUpdateFactory.newLatLng(CENTER);

// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomTo(15), 1000, null);

Here is code that puts all this together:

package com.darwinsys.mapdemos;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends Activity {
	
	public static final String TAG = MainActivity.TAG;
	private GoogleMap map;
	final LatLng CENTER = new LatLng(43.661049, -79.400917);
	
	class Data {
		public Data(float lng, float lat, String title, String snippet) {
			super();
			this.lat = (float)lat;
			this.lng = (float)lng;
			this.title = title;
			this.snippet = snippet;
		}
		float lat;
		float lng;
		String title;
		String snippet;
	}
	
	Data[] data = {
			new Data(-79.400917f,43.661049f, "New New College Res",
					"Residence building (new concrete high-rise)"),
			new Data(-79.394524f,43.655796f, "Baldwin Street",
					"Here be many good restaurants!"),
			new Data(-79.402206f,43.657688f, "College St",
					"Lots of discount computer stores if you forgot a cable or need to buy hardware."),    
			new Data(-79.390381f,43.659878f, "Queens Park Subway",
					"Quickest way to the north-south (Yonge-University-Spadina) subway/metro line"),
			new Data(-79.403732f,43.666801f, "Spadina Subway",
					"Quickest way to the east-west (Bloor-Danforth) subway/metro line"),
			new Data(-79.399696f,43.667873f, "St George Subway back door",
					"Token-only admittance, else use Spadina or Bedford entrances!"),
			new Data(-79.384163f,43.655083f, "Eaton Centre (megamall)",
					"One of the largest indoor shopping centres in eastern Canada. Runs from Dundas to Queen."),
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Log.d(TAG, "MapsActivity.onCreate()");
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
		    
		if (map==null) {
			Log.d(TAG, "Map Fragment Not Found or no Map in it!!");
			return;
		}
		
		for (Data d : data) {
		    LatLng location = new LatLng(d.lat, d.lng);
			map.addMarker(new MarkerOptions().position(location)
		          .title(d.title)
		          .snippet(d.snippet));
		}
		
		// Let the user see indoor maps where available.
		map.setIndoorEnabled(true);
		
		// Enable my-location stuff
		map.setMyLocationEnabled(true);
		
		// Move the "camera" (view position) to our center point.
		map.moveCamera(CameraUpdateFactory.newLatLng(CENTER));
                // Then animate the markers while the map is drawing,
		// since you can't combine motion and zoom setting!
                final int zoom = 14;
                map.animateCamera(CameraUpdateFactory.zoomTo(zoom), 1500, null);
	}
}

The resulting map page looks something like the following:

Attribution Text

The terms of use of the Google Android Maps API, which you agreed to when you got your API key, require you to display the attribution text, which at present is basically the Apache 2 License. You can get the (hopefully internationalized) version of the required text by calling the convenience method GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(this)

The AboutActivity for this app contains an HTML file in a WebView (loaded from the assets folder), with a TextView below that for the attribution text. The code for this is as follows:

	public void onCreate(Bundle savedInstanceState) {	
		super.onCreate(savedInstanceState);
		setContentView(R.layout.about_activity);
		
		WebView aboutView = (WebView)findViewById(R.id.about_content);
		aboutView.loadUrl("file:///android_asset/about.html");
		
		TextView tv = (TextView)findViewById(R.id.about_version_tv);
		tv.setText(GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(this));		
	}

Everything Else

There is quite a bit more capability here, resulting in there being much more that you can do with the Android Maps API V2. Among other things you can:

  • add or remove various UI controls;
  • add polygons or polylines to the map;
  • add GroundLayers (anchored to the map) or TileLayers (floating above it); in these you can do any kind of drawing;
  • and more.

This is a new API and features may be added. For example, there are several GUI controls which can be shown (the example above enables the "My Location" button), but there is not yet a way to enable the "Map Type" control. You can set the map type initially or programmatically, but you'd have to provide your own GUI for it. Nonetheless, it is quite a capable API. I urge you to explore it on your own until we get more recipes added or updated.

Download:

The source code for this project is in the Android Cookbook repository at http://github.com/IanDarwin/Android-Cookbook-Examples, in the subdirectory MapDemosV2.
krias 2014-01-12 09:37:54.518 Any new updates to V2, all web sources seam to stop about this point. I need help on custom info windows and driving rout between two markers, and Data base Markers