Display static Google Maps in Android

Hi friends!

The Google Static Map web service enables developers to dynamically create a map image based on URL parameters (i.e. latitude, longitude, zoom level etc) sent through a standard HTTP request. When called it returns the map as an image allowing developers to display it on the user interface.

As mentioned on the developer’s page, the Google Static Maps API lets you embed a Google Maps image on your web page without requiring JavaScript or any dynamic page loading. The Google Static Map service creates your map based on URL parameters sent through a standard HTTP request and returns the map as an image that you can display on your web page.

Through this post, we will learn how to display a static Google map in Android.

Pre-requisites: Eclipse IDE, Android SDK

Create a new Activity class called TestStaticMapActivity in any of your existing Android projects and add the following code!

package com.app.test;

import java.io.IOException;
import java.io.InputStream;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ImageView;

public class TestStaticMapActivity extends Activity {
	
	private ImageView iv;
	
	@Override
	public void onCreate(Bundle s){
		super.onCreate(s);
		setContentView(R.layout.activity_main);
		iv = (ImageView)findViewById(R.id.img1);
		new SendTask().execute();
		
	}
	
	private class SendTask extends AsyncTask<Bitmap, String, Bitmap>{

		@Override
		protected void onPostExecute(Bitmap bmp){
			iv.setImageBitmap(bmp);
		}

		@Override
		protected Bitmap doInBackground(Bitmap... params) {
			// TODO Auto-generated method stub
			Bitmap bm = getGoogleMapThumbnail(18.9750,72.8258);
			return bm;

		}	
		
	};

	public static Bitmap getGoogleMapThumbnail(double latitude, double longitude){
		
		String URL = "http://maps.google.com/maps/api/staticmap?center=" +latitude + "," + longitude + "&zoom=15&size=600x600&sensor=false";
		
		Bitmap bmp = null;
		HttpClient httpclient = new DefaultHttpClient();   
		HttpGet request = new HttpGet(URL); 

		InputStream in = null;
		try {
			in = httpclient.execute(request).getEntity().getContent();
			bmp = BitmapFactory.decodeStream(in);
			in.close();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return bmp;
	}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
     
    <ImageView
        android:id="@+id/img1"
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:layout_height="fill_parent">
    </ImageView>

</RelativeLayout>

Do not forget to add the android.permission.INTERNET permission in your AndroidManifest.xml file.

Save all changes. Make sure no errors are present. Run the application on an Android device and you should see the following output!

output

Display an overlay on Google Maps for Android!

Hi everyone!

The latest version of Google Maps API for Android i.e v2 includes a feature known as GroundOverlay that is used to display an overlay on the map. A GroundOverlay is basically an image that is fixed to the map.

Some of the important properties of GroundOverlay as mentioned on the developer’s page are as follows!

1. Image

The image (as an BitmapDescriptor) is to be used for this overlay. The image will be scaled to fit the position provided. You cannot change the image used in the ground overlay once it has been added to the map. You must specify an image before adding the ground overlay to the map.

2. Visibility

Indicates if the ground overlay is visible or invisible, i.e. whether it is drawn on the map. An invisible ground overlay is not drawn, but retains all of its other properties. This is optional and the default visibility is true.

3. Position

There are two ways to specify the position of the ground overlay:

Using location: You must provide an image of the ground overlay, a LatLng to which the anchor will be fixed and the width of the overlay (in meters). The anchor is by default 50% from the top of the image and 50% from the left of the image. This can be changed. You can optionally provide the height of the overlay (in meters).

Using Bounds: You must provide a LatLngBounds which will contain the image.

Through this post, we will understand the use of the GroundOverlay feature with the help of an example!

Create an Activity class named TestOverlayActivity in any of your existing Google Maps projects and add the following code.

TestOverlayActivity.java

package com.example;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.GroundOverlayOptions;
import com.google.android.gms.maps.model.LatLng;
import android.app.Dialog;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;

public class TestOverlayActivity extends FragmentActivity implements LocationListener {

	GoogleMap googleMap;
	LocationManager locationManager;
	LocationListener mLocationListener;
    //provide any location
	LatLng point1 = new LatLng(19.03160394, 72.8676239); 

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test_overlay);

		//check if Google play services is available
		int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

		// Showing status
		if(status!=ConnectionResult.SUCCESS){ 

			int requestCode = 10;
			Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
			dialog.show();

		}
		else { 

			// Getting reference to the SupportMapFragment 
			SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);

			// Getting GoogleMap object from the fragment
			googleMap = fm.getMap();

			// Enabling MyLocation Layer of Google Map
			googleMap.setMyLocationEnabled(true);

			// Getting LocationManager object from System Service LOCATION_SERVICE
			locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
			locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,0,this);
			locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 5, this);

			//add overlay
			BitmapDescriptor image = BitmapDescriptorFactory.fromResource(R.drawable.android);
			GroundOverlayOptions groundOverlay = new GroundOverlayOptions()
			.image(image)
			.position(point1, 500f)
			.transparency(0.5f);
			googleMap.addGroundOverlay(groundOverlay);

		}
	}

	@Override
	public void onLocationChanged(Location arg0) {
		// TODO Auto-generated method stub
	}

	@Override
	public void onProviderDisabled(String arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onProviderEnabled(String arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
		// TODO Auto-generated method stub

	}
}

test_overlay.xml

<?xml version="1.0" encoding="utf-8"?>

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/map"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 class="com.google.android.gms.maps.SupportMapFragment"/>

Run the above code on an Android device and you should see an image being displayed on the Google Map!

overlay_image

Reference: GroundOverlay in Android

Implement a draggable marker using Google Maps Android API v2

Hi everyone!

If you have worked on Google Maps before then this post will help you to learn something new. A Marker is basically an icon placed at a particular point on the surface of the map. Any marker includes the following properties,

1. Position

The LatLng value for the marker’s position on the map. You can change this value at any time if you want to move the marker.

2. Title

A text string that’s displayed in an info window when the user taps the marker. You can change this value at any time.

3. Snippet

Additional text that’s displayed below the title. You can change this value at any time.

4. Icon

A bitmap that’s displayed for the marker. If the icon is left unset, a default icon is displayed.

5. Drag Status

If you want to allow the user to drag the marker, set this property to true. You can change this value at any time. The default is false.

6. Visibility

By default, the marker is visible. To make the marker invisible, set this property to false. You can change this value at any time.

Through this post, we will learn how to create a draggable marker using Google Maps Android API v2!

In any of your existing Android projects, create a new Activity class named TestDragMarker and add the following code!

Note: Make sure the Android project you are working on has been configured for using Google Play Services

TestDragMarker.java

package com.example;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerDragListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class TestDragMarker extends FragmentActivity implements OnMapLongClickListener,OnMapClickListener,OnMarkerDragListener {

	private static GoogleMap map;
	
	@Override
	protected void onCreate(Bundle saveInstance) {
			super.onCreate(saveInstance);
			setContentView(R.layout.activity_map);
			
			map = ((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
			map.setOnMarkerDragListener(this);
			map.setOnMapLongClickListener(this);
			map.setOnMapClickListener(this);
			
			CameraPosition INIT =
			new CameraPosition.Builder()
			.target(new LatLng(19.0222, 72.8666))
			.zoom(17.5F)
			.bearing(300F) // orientation
			.tilt( 50F) // viewing angle
			.build();
			 
			// use map to move camera into position
			map.moveCamera( CameraUpdateFactory.newCameraPosition(INIT) );
			
			//create initial marker
			map.addMarker( new MarkerOptions()
			   .position( new LatLng(19.0216, 72.8646) )
			   .title("Location")
			   .snippet("First Marker")).showInfoWindow();
	}
	 
	
	@Override
	public void onMarkerDrag(Marker arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onMarkerDragEnd(Marker arg0) {
		// TODO Auto-generated method stub
		LatLng dragPosition = arg0.getPosition();
		double dragLat = dragPosition.latitude;
		double dragLong = dragPosition.longitude;
		Log.i("info", "on drag end :" + dragLat + " dragLong :" + dragLong);
		Toast.makeText(getApplicationContext(), "Marker Dragged..!", Toast.LENGTH_LONG).show();
	}

	@Override
	public void onMarkerDragStart(Marker arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onMapClick(LatLng arg0) {
		// TODO Auto-generated method stub
		map.animateCamera(CameraUpdateFactory.newLatLng(arg0));
	}


	@Override
	public void onMapLongClick(LatLng arg0) {
		// TODO Auto-generated method stub
	
		//create new marker when user long clicks
		map.addMarker(new MarkerOptions()
		.position(arg0)
		.draggable(true));
	}	
}

activity_map.xml


<?xml version="1.0" encoding="utf-8"?>

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/map"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          class="com.google.android.gms.maps.SupportMapFragment"/>

Make sure you have added the necessary permissions for accessing Google Maps in the AndroidManifest.xml file. Save your Activity class and run the project on an Android device. If no errors are present, you should see the following output!

before_dragged

after_dragged

Reference: Google Maps Android API v2

Tutorial #34: Using Google Maps Android API v2

Starting from December 3rd, 2012 Google had officially deprecated the use of the Google Maps Android API version 1. The new version 2 of the API automatically handles access to Google map servers, downloading of data etc. Using this version you can also add markers, polygons and overlays to a basic map and allow user interaction with the map.

Some key features provided by Google Maps Android API v2 are:

    1) Icons anchored to specific positions on the map (Markers)

    2) Sets of line segments (Polylines)

    3) Enclosed segments (Polygons)

    4) Bitmap graphics anchored to specific positions on the map (Ground Overlays)

    5) Sets of images which are displayed on top of the base map tiles (Tile Overlays)

In this tutorial I will explain how to get a Google Map API key followed by a demo of Google Maps in action on Android!

Pre-requisites: Windows 7 (64 bit OS), Eclipse IDE, Android SDK

Step 1: Obtaining the Google Map API key

To use google maps you need to get a map key. However, even before that you need to get a SHA-1 fingerprint from your jdk installation. Open command prompt, navigate to your jdk directory and use the keytool executable to generate your key.

Generate MD5 key

Generate SHA-1 fingerprint


Syntax for using keytool

C:\<path-to-jdk-dir>\bin\keytool.exe -list -alias androiddebugkey -keystore "C:\users\<user-name>\.android\debug.keystore" -storepass android -keypass android

Now, you need to sign up for the Android Maps API by logging in with your Gmail account from over here.

Create a new Android key and paste your above generated SHA-1 fingerprint along with your project package name in the box provided.

android_google_maps_2

android_google_maps_3

Step 2: Download Google play services

In order to use Google maps in your Android projects you would need to download and install the Google play services from your Android SDK manager. As you can see in the below screenshot I have already installed the play services. You would need to check the same and then install it.

Installing Google play services

Step 3: Import Google Play services library project

Once you have installed the google play services successfully, you will find a library project at location C:\path-to-adt-bundle\sdk\extras\google\google_play_services. Open Eclipse IDE and import this existing project by using File –> Import –> Existing Android Projects into workspace.

Step 4: Create new Android project

Create a new Android project named AndroidGoogleMapsDemo with package name com.example. The package name should be same as that mentioned while creating SHA-1 fingerprint in step 1. Select Target SDK as Android 4.2 and create activity named MainActivity. Also, add reference to google-play-services_lib project as follows!

android_google_maps_5

To add reference to library project, right click your Project –> Properties –> Android. Click on Add and select project.

android_google_maps_6

Make changes to AndroidManifest.xml file as follows!

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example"
    android:versionCode="1"
    android:versionName="1.0">

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />

    <permission android:name="com.example.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.example.permission.MAPS_RECEIVE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="com.mapexplore.permission.MAPS_RECEIVE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
     
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
         <!-- Your API key needs to be added over here -->
         <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="AIzaSyAJ90gij_G7VaGy9w8L6EvO-zu8CHtTLRI" />
         
    </application>
</manifest>

MainActivity.java

package com.example;

import android.os.Build;
import android.os.Bundle;
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.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.view.Menu;


@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class MainActivity extends Activity 
 {

	  static final LatLng MUMBAI = new LatLng(19.0144100, 72.8479400);
	  private GoogleMap map;

	  @Override
	  protected void onCreate(Bundle savedInstanceState) 
          {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.activity_main);
	    map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
	    map.moveCamera(CameraUpdateFactory.newLatLngZoom(MUMBAI, 15));

	    // Zoom in, animating the camera.
	    map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
	  }
}

activity_main.xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

     <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.MapFragment" />

</RelativeLayout>

Finally, run the project and you should see the following output! Thanks and happy coding! 🙂

Output