Location Based Services on Android - Part 1/3 - MyLocationOverlay

A juicy feature of Android is its capability for location based services. The combination of the integrated GPS-Device with the easy use of Google Maps allows powerful location based applications.

Anyway, the first use of these technologies contains some hazards. Therefore, I decided to write some blog entries explaining the first steps with Android and Google Maps.

The first part of this series describes the integration of the google map view and the use of the MyLocationOverlay. In the second part I demonstrate how to use an ItemizedOverlay on a google map. Third and last part of this series describes how to build a custom Overlay and show it on the map.

Part 1 - Enable Google Maps and use a MyLocationOverlay

The first part of this series contains a short description how to integrate Google Maps in an Android application and show the current location using the MyLocationOverlay.

In order to follow these steps, you should already have installed the android sdk Eclipse as IDE and created a new Android project. If you have not done this so far, look at the Android Documentation.

Integrate Google Maps in your application
We start by editing the layout definition file of the application. The following snippet shows the content of the /res/layout/main.xml file. Its contents are described below.

<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <com.google.android.maps.MapView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true"
    android:enabled="true"
    android:id="@+id/mymap"
    android:apiKey="@string/mapskey" />
  <LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/myzoom"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
  />
</RelativeLayout>

This layout definition contains a little we trick we use to position the zoom-controls at the bottom of the map. We use a RelativeLayout, which uses the whole viewport as container. This contains the Google Maps View (com.google.android.maps.MapView) and a LinearLayout. The LinearLayout will contain the Zoom-Controls of the map. Inside a RelativeLayout, Views can be positioned in relation to each other or in relation to its parent (the RelativeLayout). The map simply uses the complete viewport. For the LinearLayout (with the zoom controls) we use the abilities of the RelativeLayout and position it centered at the bottom of the RelativeLayout, above the map.

The IDs of the LinearLayout and the map are used to make the Views accessible inside the Activity.

To use the Google Maps View an API key is needed, this will be stored as string ressource referenced by the key @string/mapskey.

Get an Google Maps API key

Android only allows the installation of signed applications. Before installing an application on the emulator, Eclipse will automatically sign the application, using a debug certificate which comes along with the Android sdk. The google maps api key is based on the certificate used to sign the application. Detailed descriptions about signing an application can be found in the online documentation.

To obtain a google maps api key (using the debug certificate) you have to do the following steps:

  1. Create a md5 checksum of the debug certificate
    Find the debug.keystore

    • Vista: C:\Users\\AppData\Local\Android\debug.keystore
    • XP: C:\Dokumente und Einstellungen\\Android\debug.keystore
    • Mac, Linux: ~/.android/debug.keystore

    and call the command
    keytool -list -alias androiddebugkey -keystore .keystore -storepass android -keypass android
    The md5 checksum is generated and printed to the screen.

  2. Register the md5 checksum
    Register the generated checksum at Maps API key. A google account is required to do so.
  3. Edit ressources
    Paste the Maps API key to the resources.

The /res/strings.xml with the Maps key of my debug certificate

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<string name="app_name">LocationBasedServicesV1</string>
	<string name="mapskey">0zHDFEa6rhx5Je8xqLmDaH6kEym5ga9nxV49H5w</string>
</resources>

A detailed description how to generate the Google Maps API key for Android can be found in the reference.

Add required permissions and libraries to the manifest

The application requires 2 permissions.

  1. Google maps requires access to the internet (android.permission.INTERNET)
  2. MyLocationOverlay requires access to the GPS (android.permission.ACCESS_FINE_LOCATION)

In addition, the library Google Maps API (com.google.android.maps) must be included to the project.

The AndroidManifest.xml containing all necessary changes:

<?xml version="1.0" encoding="utf-8"?>
<manifest
	xmlns:android="http://schemas.android.com/apk/res/android"
	package="de.itemis.frey.blog.lbsv1"
	android:versionCode="100"
	android:versionName="1.0.0">
	<application
		android:icon="@drawable/icon"
		android:label="@string/app_name">
		<activity
			android:name=".LocationBasedServicesV1"
			android:label="@string/app_name">
			<intent-filter>
				<action android:name="android.intent.action.MAIN" />
				<category android:name="android.intent.category.LAUNCHER" />
			</intent-filter>
		</activity>
		<uses-library android:name="com.google.android.maps" />
	</application>
	<uses-permission android:name="android.permission.INTERNET" />
	<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

Add MyLocationOverlay to the map and init the zoomcontrols

The activity calls in its onCreate Method the two methods initMap and initMylocation.

  1. initMap
    This method initialises the zoom controls of the map and adds them to the LinearLayout.
  2. initMyLocation
    • Instantiate a new MyLocationOverlay
    • Enable the MyLocationOverlay
    • Add the overlay to the list of overlays of the map

The LocationBasedServicesV1.java

package de.itemis.frey.blog.lbsv1;
 
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
 
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
 
public class LocationBasedServicesV1 extends MapActivity {
 
	private MapView myMap;
 
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
 
		initMap();
		initMyLocation();
	}
 
	/**
	 * Initialise the map and adds the zoomcontrols to the LinearLayout.
	 */
	private void initMap() {
		myMap = (MapView) findViewById(R.id.mymap);
 
		View zoomView = myMap.getZoomControls();
		LinearLayout myzoom = (LinearLayout) findViewById(R.id.myzoom);
		myzoom.addView(zoomView);
		myMap.displayZoomControls(true);
 
	}
 
	/**
	 * Initialises the MyLocationOverlay and adds it to the overlays of the map
	 */
	private void initMyLocation() {
		MyLocationOverlay myLocOverlay = new MyLocationOverlay(this, myMap);
		myLocOverlay.enableMyLocation();
		myLocOverlay.enableCompass();
		myMap.getOverlays().add(myLocOverlay);
 
	}
 
	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}
}

The application is now ready to receive gps signals and show them using a MyLocationOverlay.

Trigger the “GPS” of the emulator

It is possible to test the application and the gps device using the emulator. First, start the application (run as android applicaition). The easiest way to emulate incoming gps signals, is by using the “DDMS” Perspective in Eclipse. There you can send Locations via the Emulator control.

However this is not possible with a german operating system. Due to a bug in android concerning the different localised date format. But you can use telnet to connect to the emulator console and send a new position to the emulator.

  1. open a terminal
  2. type “telnet localhost 5554″ - you should now be connected to the emulator
  3. send the geo fix command, for example “geo fix 9 49

The application should now show a pin at the given location. Whenever you change the position, the maps should center to this new coordinate. (This only works, when the pin was already visible before).

So that’s it. In the next part of this series, i will explain how to use a Google Map with ItemizedOverlays.

You are welcome to post comments or suggestions for improvement.

The complete series:

Autor: Andreas Frey
Datum: Saturday, 4. April 2009 12:09
Trackback: Trackback-URL Themengebiet: Google Maps API, Google Android, Location Based Services, Tutorial

Feed zum Beitrag: RSS 2.0 Diesen Artikel kommentieren

10 Kommentare

  1. 1

    Hi,

    great tutorial, thanks!

    Do you know how to add the zoom controls to an image view, do you always have to have a mapview present to obtain them from?

    Thanks

  2. 2

    Hi Paul,

    no, you dont need to use the built-in zoomcontrols. You can also use image-buttons oder image-views to control the zooming of the map.

    To do so, simply use 2 ImageButtons, one for “+”, one for “-” zoom

    
    <RelativeLayout
      ...
      >
      <com.google.android.maps.MapView
        ...
        android:id="@+id/map"
      />
       <ImageButton
        android:id="@+id/buttonPlus"
        android:src="@drawable/plus"
        android:layout_alignTop="@id/map"
        android:layout_alignLeft="@id/map"
        ...
       />
       <ImageButton
        android:id="@+id/buttonMinus"
        android:src="@drawable/minus"
        android:layout_alignTop="@id/map"
        android:layout_toRightOf="@id/buttonPlus"
        ...
       />
    </RelativeLayout>
    

    When initialising your buttons, simply use the Methods:

    theMap.getController().zoomIn();
    theMap.getController().zoomOut();
    

    to zoom the map by yourself

  3. 3

    Hi, thank you for a speedy response!

    I think I did not explain myself well.

    What I mean is how do you get to the zoom controls as they appear in the Pictures application?

    I have an image displayed which I need to zoom but I do not understand how to get the zoom controls to work with images.

    Your code showed me how to place them within a relative layout but I do not know how attach the controls?

    Thanks

  4. 4

    Hi Paul,

    Do you want to zoom a google map, or do you want to zoom an image?

  5. 5

    Hi,

    I want to zoom an image. I see the Android G1 has a Pictures application that allows the user to zoom an image using the zoom controls.

  6. 6

    Hi,

    sorry I did not try this yet. When I do i will post about it in this blog.

    Unfortunately my next steps are to continue this series.

  7. 7

    Hi,
    Thanks for your fabulous tutorial examples!
    I re-do your example in my Eclipse step by step, and it can be compled properly. However, I could not run it on Android Emulator, the error message shows that the application has stopped unexpectedly.
    I do not know how to fix it and I appreciate your response in advance.

  8. 8

    Hi,

    I have got the problem. That is due to my stupid miss “android” between “google” and “maps” in “com.google.android.maps.MapView” in main.xml.
    Thank you anyway and hope your more wonderful tutorial about android development.

  9. 9

    Hi,

    I am able to run the above sample application and get the google map, but when i send the latitude,longitude values from telnet, it doesn’t show the pin at he given location.

    Can you help me what might be the problem?

    Regards, Edwin

  10. 10

    Hi Edwin,

    sometimes the map is not positioned automatically to the new position. Try to search it on the map and then resend long/lat values.

    In addition check the following things.
    - Do you add the overlay to the map?
    - Is the permission “android.permission.ACCESS_FINE_LOCATION” set?
    - Is there an error in the logcat view?

Kommentar abgeben