Sensor Fun: Location Based Services and GPS for Android

May 30th, 2010 by

The Android SDK offers a nice API to receive information about available providers for location based services and get the current location and coordinates.

In this short tutorial we’re going to build a small activity that displays a list of available location providers and shows the current position using gps services.

Example

  • Create a new Android Project using ADT and your IDE with a package named com.hascode.android.location_app
  • Add the permissions needed to the AndroidManifest.xml – it should look like this
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    	package="com.hascode.android.location_app" android:versionCode="1"
    	android:versionName="1.0">
    	<application android:icon="@drawable/icon" android:label="@string/app_name">
    		<activity android:name=".LocationActivity" 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>
    	<uses-sdk android:minSdkVersion="7" />
     
    	<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
    	<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
    	<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
    	<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"></uses-permission>
    </manifest>
  • Create a layout with one text view and two buttons in the main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <TableLayout android:layout_width="fill_parent"
    	android:layout_height="fill_parent" android:orientation="vertical"
    	xmlns:android="http://schemas.android.com/apk/res/android">
    	<TextView android:id="@+id/output" android:layout_width="wrap_content"
    		android:layout_height="wrap_content" android:text="@string/loading">
    	</TextView>
    	<Button android:id="@+id/btShowProviders" android:layout_width="wrap_content"
    		android:layout_height="wrap_content" android:text="@string/showProviders">
    	</Button>
    	<Button android:id="@+id/btShowLocation" android:layout_width="wrap_content"
    		android:layout_height="wrap_content" android:text="@string/showLocation">
    	</Button>
    </TableLayout>
  • Externalize the strings in the strings.xml
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
     <string name="app_name">LocationApp</string>
     <string name="loading">loading...</string>
     <string name="showProviders">Show available providers</string>
     <string name="showLocation">Listen to coordinate updates</string>
    </resources>
  • Create the activity LocationActivity
    package com.hascode.android.location_app;
     
    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.location.LocationProvider;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
     
    public class LocationActivity extends Activity implements LocationListener {
    	// attrs
    	private static final String TAG = "com.hascode.android.location-app";
    	private LocationManager locationManager;
    	private static final String PROVIDER = "gps"; // for this tutorial we simply
    	// assume that this provider
    	// exists
     
    	// ui elements
    	private TextView output;
    	private Button btShowProviders;
    	private Button btShowLocation;
     
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
     
    		output = (TextView) findViewById(R.id.output);
    		btShowProviders = (Button) findViewById(R.id.btShowProviders);
    		btShowLocation = (Button) findViewById(R.id.btShowLocation);
     
    		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    		if (locationManager == null) {
    			Log.w(TAG, "no location manager found");
    			output.setText("no location manager no fun ..");
    		} else {
    			btShowProviders.setOnClickListener(new View.OnClickListener() {
    				@Override
    				public void onClick(View view) {
    					showProviders();
    				}
    			});
     
    			btShowLocation.setOnClickListener(new View.OnClickListener() {
    				@Override
    				public void onClick(View view) {
    					showLocation();
    				}
    			});
    		}
    	}
     
    	/**
    	 * shows the list of available location providers
    	 */
    	private void showProviders() {
    		List<String> providers = locationManager.getAllProviders();
    		Log.d(TAG, "available providers found: " + providers.size());
    		StringBuilder s = new StringBuilder();
    		for (String provider : providers) {
    			s.append(provider);
    			s.append("\n");
    		}
    		output.setText(s.toString());
    	}
     
    	/**
    	 * displays the current location using the gps provider
    	 */
    	private void showLocation() {
    		LocationProvider gps = locationManager.getProvider(PROVIDER);
    		if (gps == null) {
    			Log.w(TAG, "gps provider not found");
    			return;
    		}
     
    		locationManager.requestLocationUpdates(PROVIDER, 1200, 5, this);
    		Log.d(TAG, "listening to gps events started");
    	}
     
    	/*
    	 * (non-Javadoc)
    	 *
    	 * @see
    	 * android.location.LocationListener#onLocationChanged(android.location.
    	 * Location)
    	 */
    	@Override
    	public void onLocationChanged(Location location) {
    		String result = String.format(
    				"Your coords: latitude %f is longitude is %f", location
    						.getLatitude(), location.getLongitude());
    		Log.d(TAG, "location update received: " + result);
    		output.setText(result);
    	}
     
    	/*
    	 * (non-Javadoc)
    	 *
    	 * @see
    	 * android.location.LocationListener#onProviderDisabled(java.lang.String)
    	 */
    	@Override
    	public void onProviderDisabled(String provider) {
    		Log.d(TAG, "the following provider was disabled: " + provider);
    	}
     
    	/*
    	 * (non-Javadoc)
    	 *
    	 * @see
    	 * android.location.LocationListener#onProviderEnabled(java.lang.String)
    	 */
    	@Override
    	public void onProviderEnabled(String provider) {
    		Log.d(TAG, "the following provider was enabled: " + provider);
    	}
     
    	/*
    	 * (non-Javadoc)
    	 *
    	 * @see android.location.LocationListener#onStatusChanged(java.lang.String,
    	 * int, android.os.Bundle)
    	 */
    	@Override
    	public void onStatusChanged(String provider, int status, Bundle extras) {
    		Log.d(TAG, String.format(
    				"Provider status has changed. provider: %s, status: %d",
    				provider, status));
    	}
    }
  • Run the app on your emulator and use ddms or the emulator control view if you’re using eclipse like me

Screenshots

Converting to a Maven Project

If you want to use Maven with your project, take a look at this article – my pom.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.hascode.android.location_app</groupId>
 <artifactId>location-app</artifactId>
 <packaging>apk</packaging>
 <name>hasCode.com - Sample Location App</name>
 <version>0.1</version>
    <dependencies>
        <dependency>
            <groupId>android</groupId>
            <artifactId>android</artifactId>
            <version>2.1_r1</version>
           <scope>provided</scope>
        </dependency>
    </dependencies>
 
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.jayway.maven.plugins.android.generation2</groupId>
                <artifactId>maven-android-plugin</artifactId>
                <configuration>
                    <sdk>
                        <path>${env.ANDROID_HOME}</path>
                        <platform>1.6</platform>
                    </sdk>
                    <deleteConflictingFiles>true</deleteConflictingFiles>
                </configuration>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>
 </project>

Logging and Filtering

Take a look at the logs using the adb tool and filter for entries with the tag “com.hascode.android.location-app“:

adb -s emulator-5554 shell
# logcat com.hascode.android.location-app:D *:S
D/com.hascode.android.location-app(  209): available providers found: 1
D/com.hascode.android.location-app(  209): listening to gps events started
D/com.hascode.android.location-app(  209): listening to gps events started
D/com.hascode.android.location-app(  209): available providers found: 1
D/com.hascode.android.location-app(  209): listening to gps events started

Links

package com.hascode.android.location_app;

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.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class LocationActivity extends Activity implements LocationListener {
// attrs
private static final String TAG = “com.hascode.android.location-app”;
private LocationManager locationManager;
private static final String PROVIDER = “gps”; // for this tutorial we simply
// assume that this provider
// exists

// ui elements
private TextView output;
private Button btShowProviders;
private Button btShowLocation;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

output = (TextView) findViewById(R.id.output);
btShowProviders = (Button) findViewById(R.id.btShowProviders);
btShowLocation = (Button) findViewById(R.id.btShowLocation);

locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (locationManager == null) {
Log.w(TAG, “no location manager found”);
output.setText(“no location manager no fun ..”);
} else {
btShowProviders.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showProviders();
}
});

btShowLocation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showLocation();
}
});
}
}

/**
* shows the list of available location providers
*/
private void showProviders() {
List<String> providers = locationManager.getAllProviders();
Log.d(TAG, “available providers found: ” + providers.size());
StringBuilder s = new StringBuilder();
for (String provider : providers) {
s.append(provider);
s.append(“\n”);
}
output.setText(s.toString());
}

/**
* displays the current location using the gps provider
*/
private void showLocation() {
LocationProvider gps = locationManager.getProvider(PROVIDER);
if (gps == null) {
Log.w(TAG, “gps provider not found”);
return;
}

locationManager.requestLocationUpdates(PROVIDER, 1200, 5, this);
Log.d(TAG, “listening to gps events started”);
}

/*
* (non-Javadoc)
*
* @see
* android.location.LocationListener#onLocationChanged(android.location.
* Location)
*/
@Override
public void onLocationChanged(Location location) {
String result = String.format(
“Your coords: latitude %f is longitude is %f”, location
.getLatitude(), location.getLongitude());
Log.d(TAG, “location update received: ” + result);
output.setText(result);
}

/*
* (non-Javadoc)
*
* @see
* android.location.LocationListener#onProviderDisabled(java.lang.String)
*/
@Override
public void onProviderDisabled(String provider) {
Log.d(TAG, “the following provider was disabled: ” + provider);
}

/*
* (non-Javadoc)
*
* @see
* android.location.LocationListener#onProviderEnabled(java.lang.String)
*/
@Override
public void onProviderEnabled(String provider) {
Log.d(TAG, “the following provider was enabled: ” + provider);
}

/*
* (non-Javadoc)
*
* @see android.location.LocationListener#onStatusChanged(java.lang.String,
* int, android.os.Bundle)
*/
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, String.format(
“Provider status has changed. provider: %s, status: %d”,
provider, status));
}
}

Tags: , , , , , , ,

2 Responses to “Sensor Fun: Location Based Services and GPS for Android”

  1. john hewitt Says:

    thanks for the tutorial. I have one problem when i try to run. I have error x’s in the location activity and when I run I get this error: An internal error occurred during: “Launching New_configuration”. Path for project must have only one segment.

    thanks for any advice,

    john

  2. steven Says:

    Hi John,

    whats your environment? Are you using Eclipse with installed Android SDK? And running the application using Run as .. Android Application?

    greets

    steven

Leave a Reply

Please leave these two fields as-is:

Protected by Invisible Defender. Showed 403 to 80,962 bad guys.

Search
Categories