views:

335

answers:

0

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