Hi,
I am trying to write a class to track a person's location(s), and to draw the path they've taken on a MapView. This feature of the program is for the user to track their speed, distance, path, etc. while running/cycling (or whatever else) using their Android phone. This is my first Android application, and I am not sure how to do the Overlay object for the MapView. I also wanted to see if anyone had opinions on the GPS-Tracking part I have written (if it would work, if there is a better way of doing it, code examples would be helpful). I currently have this for my GPSTrackerService:
package org.drexel.itrain.logic;
import java.util.Vector;
import org.drexel.itrain.Constants;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.GpsStatus.Listener;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
public class GPSTrackingService extends Service {
private static final int MAX_REASONABLE_SPEED = 60;
private static final String TAG = "OGT.TrackingService";
private Context mContext;
private LocationManager mLocationManager;
private NotificationManager mNotificationManager;
private Notification mNotification;
private int mSatellites = 0;
private int mTrackingState = Constants.GPS_TRACKING_UNKNOWN;
private float mCurrentSpeed = 0;
private float mTotalDistance = 0;
private Location mPreviousLocation;
private Vector<Location> mTrackedLocations;
private LocationListener mLocationListener = null;
private Listener mStatusListener = null;
private IBinder binder = null;
@Override
public void onCreate() {
super.onCreate();
this.mContext = getApplicationContext();
this.mLocationManager = (LocationManager) this.mContext.getSystemService( Context.LOCATION_SERVICE );
this.mNotificationManager = (NotificationManager) this.mContext.getSystemService( Context.NOTIFICATION_SERVICE );
this.mTrackedLocations = new Vector<Location>();
this.binder = new Binder();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this.mContext);
binder = new Binder();
if(mTrackingState != Constants.GPS_TRACKING_UNKNOWN) {
createListeners();
}
}
@Override
public void onDestroy() {
destroyListeneres();
}
@Override
public IBinder onBind(Intent intent) {
return binder;
}
@Override
public boolean onUnbind(Intent intent) {
return true;
}
public boolean acceptLocation(Location proposedLocation) {
if(!(proposedLocation.hasSpeed() || proposedLocation.hasAccuracy())) {
return false;
}
else if(proposedLocation.getSpeed() >= MAX_REASONABLE_SPEED) {
return false;
}
return true;
}
public void updateNotification() {
//TODO Alert that no GPS sattelites are available (or are available)
}
public void startTracking() {
this.mTrackingState = Constants.GPS_TRACKING_STARTED;
this.mTotalDistance = 0;
this.mCurrentSpeed = 0;
this.mTrackedLocations = new Vector<Location>();
this.mPreviousLocation = null;
createListeners();
}
public void pauseTracking() {
this.mTrackingState = Constants.GPS_TRACKING_PAUSED;
this.mPreviousLocation = null;
this.mCurrentSpeed = 0;
}
public void resumeTracking() {
if(this.mTrackingState == Constants.GPS_TRACKING_STOPPED){
this.startTracking();
}
this.mTrackingState = Constants.GPS_TRACKING_STARTED;
}
public void stopTracking() {
this.mTrackingState = Constants.GPS_TRACKING_STOPPED;
destroyListeneres();
}
private void createListeners() {
/**
* LocationListener receives locations from
*/
this.mLocationListener = new LocationListener() {
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onLocationChanged(Location location) {
if(mTrackingState == Constants.GPS_TRACKING_STARTED && acceptLocation(location)) {
if(mPreviousLocation != null) {
//Add the distance between the new location and the previous location
mTotalDistance += mPreviousLocation.distanceTo(location);
}
if(location.hasSpeed()) {
mCurrentSpeed = location.getSpeed();
}
else {
mCurrentSpeed = -1; //-1 means speed N/A
}
mPreviousLocation = location;
mTrackedLocations.add(location);
}
}
};
/**
* Receives updates reguarding the GPS Status
*/
this.mStatusListener = new GpsStatus.Listener() {
@Override
public synchronized void onGpsStatusChanged(int event) {
switch( event )
{
case GpsStatus.GPS_EVENT_SATELLITE_STATUS: {
GpsStatus status = mLocationManager.getGpsStatus( null );
mSatellites = 0;
Iterable<GpsSatellite> list = status.getSatellites();
for( GpsSatellite satellite : list )
{
if( satellite.usedInFix() )
{
mSatellites++;
}
}
updateNotification();
break;
}
default:
break;
}
}
};
}
/**
* Destroys the LocationListenere and the GPSStatusListener
*/
private void destroyListeneres() {
this.mLocationListener = null;
this.mStatusListener = null;
}
/**
* Gets the total distance traveled by the
*
* @return the total distance traveled (in meters)
*/
public float getDistance() {
return mTotalDistance;
}
/**
* Gets the current speed of the last good location
*
* @return the current speed (in meters/second)
*/
public float getSpeed() {
return mCurrentSpeed;
}
}
Any assistance would be much appreciated. This is my group's first Android app, and we are a little pressed for time at the moment. The project is for a class, and is available from SourceForge (currently called iTrain, soon to be renamed).
Thanks in Advance,
Steve