Friday, September 2, 2011

Acquiring GPS location fix



GPS has opened a Pandora's box for mobile developer. There has been a huge influx of such application ranging from tracking apps to location based social networking apps.

Many of today's applications require us to get a GPS fix on the location of the device when the application is being used.

Therefore without further ado lets get into some coding.
The following snippet of codes employ a service and a broadcast receiver to get onto a location fix. It gets the most recent fix on the location and then closes the GPS updates as soon as it gets a fix.

public class FindGPSActivity extends Activity{

Intent myGpsService;
MainGpsReciever gpsReciever;
final String GPS_FILTER = "MyGPSLocation";  

protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.textlayout);
                initGpsListeners()
}



- initGpsListeners method initializes the necessary services and the recievers. 

private void initGpsListeners() {
           
            myGpsService = new Intent(this, GpsService.class);
            startService(myGpsService);
            String GPS_FILTER = getResources().getString(GPS_FILTER);
            IntentFilter mainFilter = new IntentFilter(GPS_FILTER);
            gpsReciever = new MainGpsReciever();
            registerReceiver(gpsReciever, mainFilter);
           
      }

- this is where i get my location data which i can further use in my activity.
This receiver is called from within the service which is actually looking for a GPS location. A GPS location fix is an unreliable bit of information and we cannot be sure when we might get it. it can range anywhere from 5 seconds to 5 minutes or if you are inside a huge structure like a building you might never get it unless you come out. Therefore we use a service because we do not want our location finder to be garbage collected by android.


private class MainGpsReciever extends BroadcastReceiver {

             public void onReceive(Context arg0, Intent calledIntent) {
                       
                   Constants.GPSLatitude = calledIntent.getDoubleExtra("latitude", -1);
                   Constants.GPSLongitude = calledIntent.getDoubleExtra("longitude", -1);
                   Constants.GPSSpeed = calledIntent.getFloatExtra("speed", -1);
                       
                   Log.i("GPS Demo", "Lat & Long --- "+Constants.GPSLatitude+"--"+Constants.GPSLongitude);
                   Log.i("GPS Demo", Speed --- "+Constants.GPSSpeed);
//               
                                         
             }
       }
}

This is the service class in its entirety. 

public class GpsService extends Service {

      String GPS_FILTER = "";
      Thread triggerService;
      LocationManager lm;
      GpsListener gpsLocationListener;
      boolean isRunning = true;
     
      @Override
      public void onCreate() {
           
            // TODO Auto-generated method stub
            super.onCreate();
            GPS_FILTER = “MyGPSLocation”;
           
      }
     
      @Override
      public void onStart(Intent intent, int startId) {
            // TODO Auto-generated method stub
            super.onStart(intent, startId);          
            triggerService = new Thread(new Runnable(){
                  public void run(){
                        try{
                              Looper.prepare();//Initialize the current thread as a looper.
                              lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
                              gpsLocationListener = new GpsListener();
                              long minTime = 30000; // 5 sec...
                              float minDistance = 10;
                              lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTime,
                                          minDistance, gpsLocationListener);
                              Looper.loop();
                        }catch(Exception ex){
                              System.out.println("Exception in triggerService Thread -- "+ex);
                        }
                  }
            }, "myLocationThread");
            triggerService.start();
      }
     
      @Override
      public void onDestroy() {
            // TODO Auto-generated method stub
            super.onDestroy();
            removeGpsListener();
      }
     
      @Override
      public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
      }
     
      private void removeGpsListener(){
            try{
                  lm.removeUpdates(gpsLocationListener);
            }
            catch(Exception ex){
                  System.out.println("Exception in GPSService --- "+ex);
            }
      }
     
      class GpsListener implements LocationListener{

            public void onLocationChanged(Location location) {
                  // TODO Auto-generated method stub
                  double latitude = location.getLatitude();
                  double longitude = location.getLongitude();
                  float speed = location.getSpeed();
                  Intent filterRes = new Intent(GPS_FILTER);
                  filterRes.putExtra("latitude", latitude);
                  filterRes.putExtra("longitude", longitude);
                  filterRes.putExtra("speed", speed);
                  sendBroadcast(filterRes);
            }

            public void onProviderDisabled(String provider) {
                  // TODO Auto-generated method stub
                 
            }

            public void onProviderEnabled(String provider) {
                  // TODO Auto-generated method stub
                 
            }

            public void onStatusChanged(String provider, int status, Bundle extras) {
                  // TODO Auto-generated method stub
                 
            }

      }

}