Download

My Professional Android 2 Application Development text had two very nifty examples which are worth expounding upon: Talking to the Google Maps control, called a MapView, and talking to the GPS hardware. Talking to the GPS is simpler, so I’ll start there, with the source code in its scary entirety:

 
package com.vromtr.paad.ch8.whereami;
 
import android.app.Activity;
import android.os.Bundle;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.widget.TextView;
 
public class WhereAmI extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        //Call base class onCreate
    	super.onCreate(savedInstanceState);
 
    	//"Inflate" our UI (such as it is) from our program's resource
    	setContentView(R.layout.main);
 
    	//Magic class for interacting with all the different ways
    	//a phone can stalk you.
    	LocationManager locationManager;
 
    	//We have to ask for the systemwide instance of the LocationManager class nicely.
    	//This is the name we use to ask for it.
    	String context = Context.LOCATION_SERVICE;
 
    	//We get the locationmanager by means of a Context
    	//I have no clue what a "context" is.  But it gets you stuff.
    	locationManager = (LocationManager)getSystemService(context);
 
    	//Name we use to ask to talk to the GPS
    	String provider = LocationManager.GPS_PROVIDER;
 
    	//Get last reported location from the GPS
    	//No guarantee that it was updated recently.
    	Location location = locationManager.getLastKnownLocation(provider);
 
    	//Our method
    	//Update the UI
    	updateWithNewLocation(location);
 
    	//Set up the listener to get location updates from the GPS
    	//The listener is triggered by polling the GPS, and the GPS proactively notifying our application of movements
    	int t = 5000;		//Poll the GPS every 5000 milliseconds
    	int distance = 1;	//Or update earlier if we've moved 1 meters
 
    	LocationListener myLocationListener = new LocationListener()
    	{
 
			public void onLocationChanged(Location location) {
				updateWithNewLocation(location);
 
			}
 
			public void onProviderDisabled(String provider) {
				// TODO Auto-generated method stub
 
			}
 
			public void onProviderEnabled(String provider) {
				// TODO Auto-generated method stub
 
			}
 
			public void onStatusChanged(String provider, int status,
					Bundle extras) {
				// TODO Auto-generated method stub
 
			}
 
    	};
 
    	//Hook up our event handler^W^W listener to receive updates
    	locationManager.requestLocationUpdates(provider, t, distance, myLocationListener);
 
 
    }
 
	private void updateWithNewLocation(Location location) {
 
		//We will fill this in with the latitude/longitude from "location"
		String latLongString;
 
		//Reference to our TextView (the only real component of our UI)
		TextView myLocationText;
 
		//Get a handle to our textview
		myLocationText = (TextView)findViewById(R.id.myLocationText);
 
		//If we have a location, build the string
		if (location != null)
		{
			double lat = location.getLatitude();
			double lng = location.getLongitude();
			latLongString = "Lat: " + lat + "\nLong: " + lng;
		}
		else
		{
			latLongString = "No location found.";
		}
 
		myLocationText.setText("Your current position is totally around: \n"+latLongString);
 
 
	}
}

Like practically every Java program, it starts with a package declaration and some includes. The includes aren’t really worth mentioning – if you try to use a class without including the correct package, Eclipse will underline the erroneous class, tell you what package it’s in, and offer to include it for you.

The application begins like normal: We derive a subclass from the Activity class, call the base class’s onCreate function for housekeeping, and “inflate” (display) our primary View (window).

public class WhereAmI extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        //Call base class onCreate
    	super.onCreate(savedInstanceState);
 
    	//"Inflate" our UI (such as it is) from our program's resource
    	setContentView(R.layout.main);

Following that, we create a LocationManager.

    	LocationManager locationManager;
      	String context = Context.LOCATION_SERVICE;
    	locationManager = (LocationManager)getSystemService(context);
    	String provider = LocationManager.GPS_PROVIDER;
    	Location location = locationManager.getLastKnownLocation(provider);

A LocationManager is a systemwide class that provides a layer of abstraction over all the possible different ways a phone can know where you are – GPS, cell tower triangulation, WiFi hotspot guessing, altimeter, divining rod, etc. A “context” is a string token you pass to the operating system to get a copy of this unique, system-wide class – we don’t get to instantiate a copy ourselves; it’s a singleton that belongs to the operating system, and we have to ask nicely to play with it via getSystemService.

Here, we explicitly specify the GPS with the provider string. My text suggests this is not best practices, but it serves for an example.

Finally, we get the provider’s last known location. However, the “last known location” is not guaranteed to have been set recently, or at all. So, we have to poll the GPS for current data.

This happens asynchronously, so we set up a special event handler called a LocationListener. It gets called when we get meaningful data back from the GPS.

LocationListener myLocationListener = new LocationListener()
    	{
 
			public void onLocationChanged(Location location) {
				updateWithNewLocation(location);
 
			}
        }

The updateWithNewLocation() function is pretty simple – it plasters the Location the GPS returns onto our UI. The following code finds our applications TextView control, builds a string from the new latitude and longitude, and places it in the TextView.

	private void updateWithNewLocation(Location location) {
 
		//We will fill this in with the latitude/longitude from "location"
		String latLongString;
 
		//Reference to our TextView (the only real component of our UI)
		TextView myLocationText;
 
		//Get a handle to our textview
		myLocationText = (TextView)findViewById(R.id.myLocationText);
 
		//If we have a location, build the string
		if (location != null)
		{
			double lat = location.getLatitude();
			double lng = location.getLongitude();
			latLongString = "Lat: " + lat + "\nLong: " + lng;
		}
		else
		{
			latLongString = "No location found.";
		}
 
		myLocationText.setText("Your current position is totally around: \n"+latLongString);
 
 
	}
}

Finally, we register our LocationListener event handler to receive updates from the GPS via our LocationManager:

    	int t = 5000;		//Poll the GPS every 5000 milliseconds
    	int distance = 1;	//Or update earlier if we've moved 1 meters
 
    	//Hook up our event handler^W^W listener to receive updates
    	locationManager.requestLocationUpdates(provider, t, distance, myLocationListener);

The layout isn’t interesting; you can look at it in the Workspace ZIP. Running it will yield a black TextView with GPS coordinates of your current position. (Or, if you’re running it within an emulator, whatever position you fed into the device.)