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 Application

  • 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

Resources

Article Updates

  • 2015-03-03: Table of contents added.

    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 note, that no personal information like your IP address is stored and you're not required to enter you real name.

    Comments must be approved before they are published, so please be patient after having posted a comment - it might take a short while.

    Please leave these two fields as-is:
    Search
    Tags
    Categories