Mobile Me(dia)

Shawn Van Every Shawn.Van.Every@nyu.edu
Spring 2009

Week 10 - Location

Moving from place to place

As we have discussed, mobile phones are always on, always connected, always with us and unlike phones from the passed, aren't fixed to any particular place or location.

What if our mobile phones knew where they were or if we could tell them? What benefit would that have? What additional capabilities does knowing place offer us?

Location Based Services

Location Based Services have been a holy grail of developers in the mobile space of some time. Carriers see it as a way to provide advertising (revenue) that is more applicable to the user because they are in context to where the "consumer" is.

Where are you?

Mobile implies movement but where, how?

Here are a couple of ways:

GPS (Global Positioning System): GPS was developed by the US government and subsequently opened up to anyone wishing to use it. It consists of satellites orbiting the earth sending down a signal that can be used by GPS receivers to determine their position.

In order to use GPS, you generally have to be in a non-urban setting with a clear view of the sky and have a device with a GPS reciever. The Nokia N95 phones have such a reciever and offer an interface for us to use it.

Cell Tower ID: Cell towers transmit an identification number to mobile phones. Since each tower is in a specific locaiton, you can determine a reasonable approimation of location by knowing which tower you are using. Typically a mobile phone in an urban setting would get signal from more than one tower (only using the closest one for communications purposes). Getting these id's from more than one tower allows the application to determine more precisely the location of the mobile phone.

Unfortunately, getting cell tower information isn't in the realm of JME applications on the phone. You can get it with Symbian and Python though. Databases that have cell tower locations are also somewhat hard to come by.

Fortunately, AGPS (Assisted GPS) has started to be integrated into devices. AGPS uses cell tower information coordination with GPS to give a faster and sometimes more accurate approximation of location. The N95 can be setup to use AGPS.

WiFi Positioning: As more mobile devices become WiFi enabled, using WiFi positioning systems is becoming increasingly popular. Essentially your location can be known based upon the WiFi networks that you can see and therefore your location can be determined.

Asking the user: One way to solve difficult problems is to off load that problem to the user. Often when something is technically complex, it may not be a bad idea to just ask. People know a lot! Asking in the right way, with the right constraints is the hard part.

More Information
FireEagle - Yahoo's service for reporting location. A set of APIs for updating location to be shared among many Geo aware applications.
35 Ways to Find Your Location by Chris Heathcote, Nokia for O'Reilly's Emerging Technology Conference 2004

Examples:

TwitterVision, FlickrVision, SpinVision.tv

Socialight

GPS with JME/Mobile Processing

Using: MSimpleLocation
import processing.core.*;
import com.mobvcasting.msimplelocation.*;

public class MSimpleLocationTest extends PMIDlet 
{	
	MSimpleLocation loccap;
	
	String captureKey = "Get Location";
    String testKey = "Test Reading";
	String location = "No Location Yet";

    PFont font;
	
	public void setup()
	{
	    loccap = new MSimpleLocation((PMIDlet)this);
	    softkey(captureKey);
        font = loadFont("ArialMT-12.mvlw");
        textFont(font);
	}
	
	public void draw()
	{
          background(255);
          text(location,10,15);
	}

	public void softkeyPressed(String label)
	{
		if (label.equals(captureKey))
		{
			location = "No Location Yet";
			loccap.startLocationSearch(10);
			softkey(testKey);
			redraw();
		}
        else if (label.equals(testKey))
        {
        	location = "reading: " + loccap.getStatus() + " " + loccap.getLatitude(); 
        }
	}
	
	public void libraryEvent(Object library, int event, Object data)
	{
		try
		{
              if (event == 2)
              {
		location = "found location " + ((MSimpleLocation)library).getLatitude() + " " + event;
              }
              else if (event == 3)
              {
                 location = "failed search"; 
              }
		}
		catch (Exception e)
		{
			location = e.getMessage();
		}
	}
}
		
		
		
What could we do with this? How about using it to determine location and placing the content on a map? How about notifications of people near by? How about just geolocating media or sending media back to the user based on where they are?

More Information
J2ME and Location Based Services
JSR 179: Location API for J2METM

GPS with Android

Android, like Mobile Processing/JME gives us the ability to utilize GPS in the phone. Here is a quick example:
package com.mobvcasting.locationexample;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class LocationExample extends Activity implements LocationListener 
{
    private static final int MENU_FIND_LOCATION = 1;

	TextView latTV;
	TextView lngTV;

	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
                
        setContentView(R.layout.main);
        
        latTV = (TextView) this.findViewById(R.id.lattv);
        latTV.setText("Started");
        lngTV = (TextView) this.findViewById(R.id.lngtv);
        
    }
        
    /* Creates the menu items */
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, MENU_FIND_LOCATION, 0, "Find Location");
        return true;
    }

    /* Handles item selections */
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
	        case MENU_FIND_LOCATION:
	        	latTV.setText("Searching");
	            findLocation();	        	
	            return true;
        }
        return false;
    }
    
    public void findLocation()
    {
    	latTV.setText("button pushed");

    	LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    	List locationProviders = locationManager.getAllProviders();
    	
    	if (!locationProviders.isEmpty())
    	{
    		// Use first location provider
    		String defaultLocationProvider = locationProviders.get(0);
    		latTV.setText(defaultLocationProvider);
    		if (locationProviders.size() > 1)
    			lngTV.setText(locationProviders.get(1));
    		
    		try
    		{
    			// Every Minute
			locationManager.requestLocationUpdates("network", 60000, 0, this);
			// You could use "gps" in place of "network" for more accuracy 
    			
    			Location currentLocation = locationManager.getLastKnownLocation("network");
			// Same thing here with "gps" in place of "network"

    			Double lat = currentLocation.getLatitude()*1E6;
    	    	Double lng = currentLocation.getLongitude()*1E6;
    	    	    	
    	    	latTV.setText("" + lat);
    	    	lngTV.setText("" + lng);
    			
    		}
    		catch (Exception e)
    		{
    			lngTV.setText(e.toString());
    		}
    	}
    	
    }    
    
    public void onLocationChanged(Location currentLocation)
    {
    	Double lat = currentLocation.getLatitude()*1E5;
    	Double lng = currentLocation.getLongitude()*1E5;
    	    	
    	latTV.setText("" + lat);
    	lngTV.setText("" + lng);
    }
    
	public void onProviderDisabled(String arg0) {		
	}

	public void onProviderEnabled(String provider) {
	}

	public void onStatusChanged(String provider, int status, Bundle extras) {
	}
}
This sample code relies upon having a two TextView's defined in layout/main.xml. One of them with the id: lattv and the other with lngtv. Also to use location services on Android phones, you need to update the AndroidManifest.xml file with a "Uses Permission" field set to be android.permission.ACCESS_FINE_LOCATION.