Setup Google Play services SDK in Eclipse

google-play-logo11

The Google Play services SDK is an extension to the Android SDK and is available as a downloadable package from the SDK Manager. The download includes the client library and code samples. To develop using the Google Play services APIs, you must download the Google Play services SDK. Google Play services is not supported on the Android emulator, a physical…

Read More »

Customize Google Maps

Customize Google Maps
Overview The Maps API allows you to Customize Google Maps look and feel of the map. Custom markers will help the user differentiate between different features of the campus (such as classrooms, bathrooms and studentfacilities). A custom legend will communicate these different types of map features, and a custom map style will help make the map overlays stand out….

Read More »

 

Creating a Mobile Event Calendar

Mobile-Calendar_Preview
This tutorial describes how to build an HTML5-based mobile calendar to track conferences and events that run on iOS and Android phones using a mobile version of dhtmlxScheduler (open source, GPL). At the end, users will be able to add and edit events, select the conference location on Google Maps, and see the events in day, month, or list views….

Read More »

 

Google Map Geocoding Tutorial with Example

 

google-map-reverse-geocodingGoogle Map API has been a great way to show geographical information on web. A lot of mashup tools like this, have been created around Google Maps to show a wide variety of data. In my previous article about Introduction to Google Maps API, I had described basic APIs to integrate Google Map in your webpage. In this small article we will discuss a great feature of Google Maps API that can be used to locate any City/Country/Place on Map. This is called Geocoding.

Google Maps API provides a wonderful API called Geocoding API that enables you to fetch any location and pin point it on Google Map. GClientGeocoder is the class that we use to get the geocoder that get us the location. We will use getLatLng() method to get latitude/longitude of any location.
Check the following code.

var place =  "New York";
geocoder = new GClientGeocoder();
geocoder.getLatLng(place, function(point) {
    if (!point) {
        alert(place + " not found");
    } else {
        var info = "<h3>"+place+"</h3>Latitude: "+point.y+"  Longitude:"+point.x;
        var marker = new GMarker(point);
        map.addOverlay(marker);
        marker.openInfoWindowHtml(info);
    }
});

In above code snippet we passed string “New York” and a handler function to getLatLng() method of GClientGeocoder. GClientGeocoder class will call google server for the location and when it gets the result, it pass the result to the handler function that we specified. Thus handler function will get point (GPoint) object from which we can get the latitude and longitude of location. In above code we have created a marker and placed it on the map.

Online Demo

Google Map Reverse Geocode Example

 

Placing multiple markers on a Google Map

English: Coogee Beach

Scroll down and copy/paste the last script in the head of your page. Add onLoad=”initializeMaps” to you body tag and put an element with id=”map_canvas” in your page. Be sure to give it dimensions and your ready to go! Oh, and don’t forget to include the Google Maps API..

Lets keep it simple. Take the base map script that we also used in our previous tutorials:

function initializeMaps() {
var latlng = new google.maps.LatLng(-33.92, 151.25);
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false
};
var map = new google.maps.Map(document.getElementById(“map_canvas”),myOptions);
}

Before we initialize this map you need an array (that’s a list) with locations and titles. That looks like this:

var markers = [
[‘Bondi Beach‘, -33.890542, 151.274856],
[‘Coogee Beach‘, -33.923036, 151.259052],
[‘Cronulla Beach‘, -34.028249, 151.157507],
[‘Manly Beach‘, -33.80010128657071, 151.28747820854187],
[‘Maroubra Beach‘, -33.950198, 151.259302]
];

This code is quite easy. Every line in this array stands for a marker. First value is the title of the marker and the second and last form the locational latitude and longitude.

Now lets add a few lines of code to out base script to loop through these marker list and place those markers on the map:

var infowindow = new google.maps.InfoWindow(), marker, i;
for (i = 0; i < markers.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(markers[i][1], markers[i][2]),
map: map
});
google.maps.event.addListener(marker, ‘click’, (function(marker, i) {
return function() {
infowindow.setContent(markers[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}

That’s all. It’s that easy!

The complete copy-and-paste script

var markers = [
[‘Bondi Beach’, -33.890542, 151.274856],
[‘Coogee Beach’, -33.923036, 151.259052],
[‘Cronulla Beach’, -34.028249, 151.157507],
[‘Manly Beach’, -33.80010128657071, 151.28747820854187],
[‘Maroubra Beach’, -33.950198, 151.259302]
];

function initializeMaps() {
var latlng = new google.maps.LatLng(-33.92, 151.25);
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false
};
var map = new google.maps.Map(document.getElementById(“map_canvas”),myOptions);
var infowindow = new google.maps.InfoWindow(), marker, i;
for (i = 0; i < markers.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(markers[i][1], markers[i][2]),
map: map
});
google.maps.event.addListener(marker, ‘click’, (function(marker, i) {
return function() {
infowindow.setContent(markers[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
}

Auto-center map around markers

I changed the above script and added a few lines of code to automatically center and zoom the map around the markers. This can easilly be done with the LatLngBounds() function from the Google Maps API (v3):

var bounds = new google.maps.LatLngBounds();
// in the marker-drawing loop:
bounds.extend(pos);
// after the loop:
map.fitBounds(bounds);

If these lines are included in the script, it looks like this:

var markers = [
[‘Bondi Beach’, -33.890542, 151.274856],
[‘Coogee Beach’, -33.923036, 151.259052],
[‘Cronulla Beach’, -34.028249, 151.157507],
[‘Manly Beach’, -33.80010128657071, 151.28747820854187],
[‘Maroubra Beach’, -33.950198, 151.259302]
];

function initializeMaps() {
var myOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false
};
var map = new google.maps.Map(document.getElementById(“map_canvas”),myOptions);
var infowindow = new google.maps.InfoWindow();
var marker, i;
var bounds = new google.maps.LatLngBounds();

for (i = 0; i < markers.length; i++) {
var pos = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(pos);
marker = new google.maps.Marker({
position: pos,
map: map
});
google.maps.event.addListener(marker, ‘click’, (function(marker, i) {
return function() {
infowindow.setContent(markers[i][0]);
infowindow.open(map, marker);
}
}
})(marker, i));
map.fitBounds(bounds);
}

Google Maps in Android – Tutorial

English: GPS navigation solution running on a ...
Image via Wikipedia
English: Screenshot of Android Froyo 2.2 runni...
Image via Wikipedia
Google Map Maker
Image via Wikipedia

Android Location API and Google Maps

This tutorial describes the usage of the Android Location API, the usage of Google Maps and the Geolocation API. It is based on Eclipse 3.7, Java 1.6 and Android 4.0 (Ice Cream Sandwich) (Gingerbread).

1. Android Basics

The following assumes that you have already basic knowledge in Android development. Please check the Android development tutorial for the basics.

2. Android Location API

2.1. Android Location API

Most Android devices allow to determine the current geolocation. This can be done via a GPS (Global Positioning System) device, via cell tower triangulation or via wifi networks for which the geolocation is known. Android contains the android.location package which provides the API to determine the current geo position.

The LocationManager provides access to the Android location service. This services allows to access location providers, to register location update listeners and proximity alerts and more.

The LocationProvider class provides location data via the Location class. The LocationProvider class is the superclass of the different location providers which deliver the information about the current location.

The Android device might have several LocationProvider available and you can select one of them. For a flexible selection of the best location provider use a Criteria object in which you can define how the provider should be selected.

You can register a LocationListener object with the LocationManager class to receive periodic updates about the geoposition.

You can also register an Intent which allows to define a proximity alert, this alert will be triggered if the device enters a area given by a longitude, latitude and radius (proximity alert).

2.2. Forward and reverse Geocoding

The Geocoder class allows to determine the geo-coordinates (longitude, laditude) for a given address and possible addresses for given geo-coordinates.

This process is known as forward and reverse geocoding.

2.3. Security

If you want to access the GSP then you need the ACCESS_FINE_LOCATION permission. Otherwise you need the ACCESS_COARSE_LOCATION.

2.4. Setting the geoposition

You can use the “DDMS” Perspective of Eclipse to send your geoposition to the emulator or a connected device. For open this Perspective select Window → Open Perspective → Other → DDMS.

In the Emulator Control part you can enter the geocoordinates and press “Send.”

You can als set the geoposition the Android emulator via telnet. Open a console and connect to your device. The port number of your device can be seen in the title area of your emulator.

				
telnet localhost 5554

Set the position via the following command.

				
geo fix 13.24 52.31

3. How to check if the LocationProvider is available

You can find out if a LocationManager is enabled via the isProviderEnabled() method. If its not enabled you can send the user to the settings via an Intent with the Settings.ACTION_LOCATION_SOURCE_SETTINGS action for the android.provider.Settings class.

			
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean enabled = service
	.isProviderEnabled(LocationManager.GPS_PROVIDER);

// Check if enabled and if not send user to the GSP settings
// Better solution would be to display a dialog and suggesting to 
// go to the settings
if (!enabled) {
  Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
	startActivity(intent);
}

Typically you would open an AlarmDialog prompt the user and if he wants to enable GPS or if the application should be canceled.

You cannot enable the GPS directly in your code, the user has to do this.

4. Activating the GPS module on the device

You need to activate GPS on your test device. If you test on the emulator and its not activated you “null” if you try to use a LocationManager.

The Google Map Activity should automatically activate the GPS device in the emulator but if you want to use the location manager directly you need to do this yourself. Currently their seems to be an issue with this.

Start Google Maps on the emulator and request the current geo-position, this will allow you to activate the GPS. Send new GPS coordinates to the Android emulator.

5. Tutorial: Using the Android Location API

Create a new project called “de.vogella.android.locationapi.simple” with the Activity called “ShowLocationActivity”.

This example will not use the Google Map therefore is also runs on an Android device.

Change your “main.xml” layout file from the “res/layout” folder to the following:

				
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="40dip"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/TextView01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dip"
            android:layout_marginRight="5dip"
            android:text="Latitude: "
            android:textSize="20dip" >
        </TextView>

        <TextView
            android:id="@+id/TextView02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="unknown"
            android:textSize="20dip" >
        </TextView>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/TextView03"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dip"
            android:layout_marginRight="5dip"
            android:text="Longitute: "
            android:textSize="20dip" >
        </TextView>

        <TextView
            android:id="@+id/TextView04"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="unknown"
            android:textSize="20dip" >
        </TextView>
    </LinearLayout>

</LinearLayout>

5.2. Add permissions

Add the following permissions to your application in your “AndroidManifest.xml” file

  • INTERNET
  • ACCESS_FINE_LOCATION
  • ACCESS_COARSE_LOCATION

5.3. Activity

Change ShowLocationActivity to the following. It queries the location manager and display the queried values in the activity.

package de.vogella.android.locationsapi.simple;

import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class ShowLocationActivity extends Activity implements LocationListener {
	private TextView latituteField;
	private TextView longitudeField;
	private LocationManager locationManager;
	private String provider;
/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		latituteField = (TextView) findViewById(R.id.TextView02);
		longitudeField = (TextView) findViewById(R.id.TextView04);

		// Get the location manager
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		// Define the criteria how to select the locatioin provider -> use
		// default
		Criteria criteria = new Criteria();
		provider = locationManager.getBestProvider(criteria, false);
		Location location = locationManager.getLastKnownLocation(provider);

		// Initialize the location fields
		if (location != null) {
			System.out.println("Provider " + provider + " has been selected.");
			int lat = (int) (location.getLatitude());
			int lng = (int) (location.getLongitude());
			latituteField.setText(String.valueOf(lat));
			longitudeField.setText(String.valueOf(lng));
		} else {
			latituteField.setText("Provider not available");
			longitudeField.setText("Provider not available");
		}
	}

	/* Request updates at startup */
	@Override
	protected void onResume() {
		super.onResume();
		locationManager.requestLocationUpdates(provider, 400, 1, this);
	}

	/* Remove the locationlistener updates when Activity is paused */
	@Override
	protected void onPause() {
		super.onPause();
		locationManager.removeUpdates(this);
	}

	@Override
	public void onLocationChanged(Location location) {
		int lat = (int) (location.getLatitude());
		int lng = (int) (location.getLongitude());
		latituteField.setText(String.valueOf(lat));
		longitudeField.setText(String.valueOf(lng));
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onProviderEnabled(String provider) {
		Toast.makeText(this, "Enabled new provider " + provider,
				Toast.LENGTH_SHORT).show();

	}

	@Override
	public void onProviderDisabled(String provider) {
		Toast.makeText(this, "Disabled provider " + provider,
				Toast.LENGTH_SHORT).show();
	}
}

5.4. Run and Test

If you using the emulator send some geo-coordinates to your device. These geo-coordinate should be displayed as soon as you press the button.

6. Google Maps

6.1. MapsView

Google provides via the com.google.android.maps package a library for using the MapView in your application. You require an additional key to use them. This key will be specified in the View which displays the map.

You need to add the following uses-library statement to your AndroidManifest.xml file. The project creation wizard does this automatically if you select a Google API version.

				
<uses-library android:required="true" android:name="com.google.android.maps"></uses-library>

The usage of MapView requires the permission to access the Internet, as the data displayed in the MapView is downloaded from the Internet.

6.2. MapsActivity

The MapActivity class extends the Activity class and provides the life-cycle management and the services for displaying a MapView widget.

MapActivity simplify the handling MapViews similar to ListActivity simplifies the usage of ListViews.

A MapView is typically defined in the XML layout file used by the MapActivity and requires the API key in the “android:apiKey” attribute. A MapView can be used with other user interface components in the same layout.

The MapController class can be used to interact with the MapView, e.g. by moving it. A Geopoint is a position described via latitude and longitude.

6.3. OverlayItem

You can also draw OverlayItem on the map. These are typical graphics which you want to display on the map.

6.4. maps library usage declaration

You must declare that your application uses the com.google.android.maps library in the application of your AndroidManifest.xml file. Please note that the usage declaration must be in the application tag otherwise you get java.lang.ClassNotFoundException for your Activity.

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

    <uses-sdk android:minSdkVersion="15" />

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="com.google.android.maps" >
        </uses-library>

        <activity
            android:name="MapViewDemo"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

7. Device with Google API

In case you want to use Google Maps in your emulator you have to create a device which supports the Google API’s. This requires that you also install the “Google API”. During device creation select the target Google API’s in the version of your SDK.

8. Google Map key

To use Google Maps you need an additional key. See for following description:

			
http://code.google.com/android/add-ons/google-apis/mapkey.html

This process is a little bit time consuming and involves creating a value on the command line. This values is needed as input for a website which allow to create the key.

9. Google Maps

9.1. Create Project

Create a new Android project called “de.vogella.android.locationapi.maps” with an Activity called “ShowMapActivity”. Make sure to select the “Google API” als Target.

Add the following permissions to your application.

  • INTERNET
  • ACCESS_FINE_LOCATION
  • ACCESS_COARSE_LOCATION

9.2. Google Map library

You need to add the Google maps library to your application. Add “uses library” to “AndroidManifest.xml”.

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

    <uses-sdk android:minSdkVersion="15" />

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="com.google.android.maps" >
        </uses-library>

        <activity
            android:name="MapViewDemo"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

9.3. Overlays

Create the following class. We will later use an image called “point”. But one icon with this name in your drawable folders.

				
package de.vogella.android.locationapi.maps;

import android.graphics.drawable.Drawable;

import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;

public class MyOverlays extends ItemizedOverlay<OverlayItem> {

	private static int maxNum = 3;
	private OverlayItem overlays[] = new OverlayItem[maxNum];
	private int index = 0;
	private boolean full = false;
	private MyOverlays itemizedoverlay;

	public MyOverlays(Drawable defaultMarker) {
		super(boundCenterBottom(defaultMarker));
	}

	@Override
	protected OverlayItem createItem(int i) {
		return overlays[i];
	}

	@Override
	public int size() {
		if (full) {
			return overlays.length;
		} else {
			return index;
		}

	}

	public void addOverlay(OverlayItem overlay) {
		if (index < maxNum) {
			overlays[index] = overlay;
		} else {
			index = 0;
			full = true;
			overlays[index] = overlay;
		}
		index++;
		populate();
	}

}

9.4. Layout

The next step requires that you have created a valid key for using the MapView widget.

Change the “main.xml” layout file in your “res/layout” folder to the following. and replace “Your Maps API Key” with your Google Maps API key.

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

    <com.google.android.maps.MapView
        android:id="@+id/mapview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:apiKey="Your Maps API Key"
        android:clickable="true" />

</RelativeLayout>

9.5. Activity

Change your Activity to the following. This Activity use an LocationListner to update the MapView with the current location.

				
package de.vogella.android.locationapi.maps;

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.widget.LinearLayout;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;

public class ShowMapActivity extends MapActivity {

	private MapController mapController;
	private MapView mapView;
	private LocationManager locationManager;
	private MyOverlays itemizedoverlay;

	public void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		setContentView(R.layout.main); // bind the layout to the activity

		// create a map view
		LinearLayout linearLayout = (LinearLayout) findViewById(R.id.main);
		mapView = (MapView) findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true);
		mapView.setStreetView(true);
		mapController = mapView.getController();
		mapController.setZoom(14); // Zoon 1 is world view
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
				0, new GeoUpdateHandler());

		Drawable drawable = this.getResources().getDrawable(R.drawable.point);
		itemizedoverlay = new MyOverlays(drawable);
		createMarker();
	}

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

	public class GeoUpdateHandler implements LocationListener {

		@Override
		public void onLocationChanged(Location location) {
			int lat = (int) (location.getLatitude() * 1E6);
			int lng = (int) (location.getLongitude() * 1E6);
			GeoPoint point = new GeoPoint(lat, lng);
			createMarker();
			mapController.animateTo(point); // mapController.setCenter(point);

		}		@Override
		public void onProviderDisabled(String provider) {
		}		@Override
		public void onProviderEnabled(String provider) {
		}		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}	private void createMarker() {
		GeoPoint p = mapView.getMapCenter();
		OverlayItem overlayitem = new OverlayItem(p, "", "");
		itemizedoverlay.addOverlay(overlayitem);
		mapView.getOverlays().add(itemizedoverlay);
	}
}

9.6. Run and Test

Run and test your application. You should be able to zoom in and out and send new geocoordinates to your map via the Emulator .

It will also draw Overlays on the Map.

10. Thank you