2

I have a LocationService which starts onResume() of the MainActivity and stops onDestroy().

@Override
protected void onResume() {
    super.onResume();
    //Start the service using alaram manager
    //If its not running currently
    if (isLocationServiceRunning(this)) {
        am = (AlarmManager) getSystemService(ALARM_SERVICE);
        Intent intent = new Intent(this, LocationService.class);
        pi = PendingIntent.getService(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        am.cancel(pi);
        am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                SystemClock.elapsedRealtime(), 1 * 60 * 1000, pi);
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (isLocationServiceRunning(this)) {
        stopService(new Intent(this, LocationService.class));
        if (am != null && pi != null) {
            am.cancel(pi);
        }
    }
}

LocationService.java

public class LocationService extends Service implements LocationListener {

    public static double curLat = 0.0;
    public static double curLng = 0.0;
    private LocationManager mgr;
    private String best;
    private Location location;
    private Location currentBestLocation;
    private static final int TWO_MINUTES = 1000 * 60 * 2;

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
        boolean gps_enabled = mgr
                .isProviderEnabled(LocationManager.GPS_PROVIDER);

        if (gps_enabled) {

            // If GPS is enabled, set criteria as ACCURACY_FINE
            // and get the best provider(which usually will be GPS_PROVIDER)
            Criteria criteria = new Criteria();
            criteria.setAccuracy(Criteria.ACCURACY_FINE);

            best = mgr.getBestProvider(criteria, true);
            // getLastKnownLocation so that user don't need to wait
            location = mgr.getLastKnownLocation(best);
            if (location == null) {
                // request for a single update, and try again.
                // Later will request for updates every 10 mins
                mgr.requestSingleUpdate(criteria, this, null);
                location = mgr
                        .getLastKnownLocation(LocationManager.GPS_PROVIDER);
            }
            if (location != null) {
                // If the GPS gives a location, update curLat and curLng
                dumpLocation(location);
            } else {
                // If the location is still null, go for NETWORK_PROVIDER
                best = LocationManager.NETWORK_PROVIDER;
                location = mgr.getLastKnownLocation(best);
                if (location != null) {
                    // If the NETWORK gives a location, update curLat and curLng
                    dumpLocation(location);
                }
            }
            // Register the Location Manager for updates, with both the
            // providers
            // Since GPS updates are expensive, we ask update every 10 mins and
            // unregister updates if GPS is disabled in onProviderDisabled
            // callback
            mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                    10 * 60 * 1000, 50, this);
            // NETWORK_PROVIDER updates every 20 secs
            mgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                    20 * 1000, 0, this);

            return START_NOT_STICKY;
        } else {
            // If GPS is disables, go with NETWORK_PROVIDER
            best = LocationManager.NETWORK_PROVIDER;
            location = mgr.getLastKnownLocation(best);
            if (location != null) {
                dumpLocation(location);
            }
            // Register NETWORK_PROVIDER for updates every 20 secs
            mgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                    20 * 1000, 0, this);
            return START_NOT_STICKY;
        }
    }

    private void dumpLocation(Location l) {
        // Called to update the curLat and curLng.
        currentBestLocation = l;
        SimpleDateFormat s = new SimpleDateFormat("dd/MM/yyyy:hh:mm:ss",
                Locale.ENGLISH);
        String format = s.format(l.getTime());
        try {
            Geocoder coder = new Geocoder(this);
            List<Address> address;
            Address location = null;
            address = coder.getFromLocation(l.getLatitude(), l.getLongitude(),
                    1);
            location = address.get(0);
        } catch (Exception e) {
            Log.e("Exception while getting address", e.getMessage() + "");
        }
        curLat = l.getLatitude();
        curLng = l.getLongitude();
    }

    @Override
    public void onLocationChanged(Location location) {
        // called when location is changed, since we registered Location
        // Providers
        // for updates
        if (isBetterLocation(location, currentBestLocation)) {
            dumpLocation(location);
        } else {
            Log.d("Not a Better Location", "Ignore");
        }
    }

    @Override
    public void onProviderDisabled(String provider) {
        // Check if best(the currently being used provider) is not null
        if (best != null) {
            // if best and disabled provider are same, the remove updates
            if ((provider.equalsIgnoreCase(LocationManager.GPS_PROVIDER) && best
                    .equals(LocationManager.GPS_PROVIDER))
                    || provider
                            .equalsIgnoreCase(LocationManager.NETWORK_PROVIDER)
                    && best.equals(LocationManager.NETWORK_PROVIDER)) {
                if (mgr != null) {
                    mgr.removeUpdates(this);
                }
            }
        }
    }

    @Override
    public void onProviderEnabled(String provider) {
        // This will be taken care in the onStartCommand where if gps_enabled
        // case is used.
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // No need to care about, because any thing like OUT_OF_SERVICE occurs,
        // location being fetched will be null and such cases are handled above.
        if ((provider.equals(LocationManager.GPS_PROVIDER))
                && (LocationProvider.OUT_OF_SERVICE == status)) {
            if (mgr != null) {
                mgr.removeUpdates(this);
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // triggered when we call stopService(LocationService);
        // which is done in onDestroy of MainActivity
        // Because LocationService must be stopped
        // when application is closed to avoid data usage
        if (mgr != null) {
            mgr.removeUpdates(this);
        }
    }

    protected boolean isBetterLocation(Location location,
            Location currentBestLocation) {
        if (currentBestLocation == null) {
            // A new location is always better than no location
            return true;
        }

        // Check whether the new location fix is newer or older
        long timeDelta = location.getTime() - currentBestLocation.getTime();
        boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
        boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
        boolean isNewer = timeDelta > 0;

        // If it's been more than two minutes since the current location, use
        // the new location
        // because the user has likely moved
        if (isSignificantlyNewer) {
            return true;
            // If the new location is more than two minutes older, it must be
            // worse
        } else if (isSignificantlyOlder) {
            return false;
        }

        // Check whether the new location fix is more or less accurate
        int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
                .getAccuracy());
        boolean isLessAccurate = accuracyDelta > 0;
        boolean isMoreAccurate = accuracyDelta < 0;
        boolean isSignificantlyLessAccurate = accuracyDelta > 200;

        // Check if the old and new location are from the same provider
        boolean isFromSameProvider = isSameProvider(location.getProvider(),
                currentBestLocation.getProvider());

        // Not significantly newer or older, so check for Accuracy
        if (isMoreAccurate) {
            // If more accurate return true
            return true;
        } else if (isNewer && !isLessAccurate) {
            // Same accuracy but newer, return true
            return true;
        } else if (isNewer && !isSignificantlyLessAccurate
                && isFromSameProvider) {
            // Accuracy is less (not much though) but is new, so if from same
            // provider return true
            return true;
        }
        return false;
    }

    // Checks whether two providers are the same
    private boolean isSameProvider(String provider1, String provider2) {
        if (provider1 == null) {
            return provider2 == null;
        }
        return provider1.equals(provider2);
    }
}

The service surely starts and stops as expected and I can see the location details in log, which are fine.

The problem if when I move to a complete different location(300 miles), the curLat and curLng values still remain as that of the old, when I open the application.

Is it because I am not running the service when the device is in motion(because my application is not running)?

Because when I open some other application like FourSquare(which gets the correct location) and then reopen my application, then it shows the correct location.

What else should I do to refresh the location properly.

Archie.bpgc
  • 23,812
  • 38
  • 150
  • 226
  • why are you not Starting your service in oncraete rather in onresume when the Application is not in OS stack it will be intialized and 1st called method is oncreate after that if application is resting in back ground on repopping onresume will be called so try it in oncreate rather just in onresume – Usman Kurd Nov 13 '13 at 05:50
  • i think islocationservice returns false, also try with return Service.START_STICKY; – Kalai.G Nov 13 '13 at 05:52
  • @UsmanKurd `onCreate()` eventually Calls `onResume()`. More over I have no problem in running the service, The problem is with the Service not refreshing the location. – Archie.bpgc Nov 13 '13 at 06:09
  • How are you checking curLat and curLng? You say they are old. How are you getting them and viewing them? – Sherif elKhatib Nov 15 '13 at 11:22
  • @SherifelKhatib I use the GeoCoder to get the address. – Archie.bpgc Nov 15 '13 at 11:39
  • Ok I think `onLocationChanged` is never called. Your service starts and uses the old location. Can you please double check – Sherif elKhatib Nov 15 '13 at 11:45
  • My `onLocationChanged` is being called. Where I check for `isBetter` and use it if its better. – Archie.bpgc Nov 15 '13 at 11:55
  • Ok but your MainActivity is not polling the new Locations. When are you reading the curLat and curLng in your MainActivity. Is it in `onServiceConnected`? – Sherif elKhatib Nov 15 '13 at 12:47
  • Not just MainActivity, but all the Activities reads the curLat, curLng whenever needed. The LocationService keeps on running and updates the curLat, curLng. – Archie.bpgc Nov 15 '13 at 13:06

8 Answers8

3

You code looks perfectly fine if you want to get the location in the foreground. I have gone through in the deep and get to know that in the onDestroy you have stopped the service and alarms also. hence as and when the current app is going to background and the onDestroy is called by system then the code fails to update the location in the background. more over when you launch the application again it will start the service and very first time get the older location which was cached.

when other application updates the location you will get that location according to documentation of the mgr.getLastKnownLocation(best).

Hence to solve this problem do not use alarm here to start service in repeating manner or destory it.

simply start the service and in the onStartCommand ask for the update of the location. and if you want to get rid of the location updates, use removeLocationUpdates(LocationListener) .

Examples are given here http://developer.android.com/training/location/receive-location-updates.html

Dinesh Prajapati
  • 9,274
  • 5
  • 30
  • 47
3

I think your problem is here

best = mgr.getBestProvider(criteria, true);
// getLastKnownLocation so that user don't need to wait
location = mgr.getLastKnownLocation(best);
if (location == null) {
     // request for a single update, and try again.
     // Later will request for updates every 10 mins
     mgr.requestSingleUpdate(criteria, this, null);
     location = mgr
             .getLastKnownLocation(LocationManager.GPS_PROVIDER);
 }

because there was previously a location location = mgr.getLastKnownLocation(best); returns that location without starting the provider (see the android documentation. So the location is not null and mgr.requestSingleUpdate(criteria, this, null); is never run.

To get up to date location data a provider must be started.

so a correction could be:

best = mgr.getBestProvider(criteria, true);
// getLastKnownLocation so that user don't need to wait
mgr.requestSingleUpdate(best, this, null);
location = mgr.getLastKnownLocation(best);

Also I'm not sure if it is intended but this service will use the network provider even when GPS data is available and more accurate (due to the 10 minute and 2 minute times chosen for GPS updates and data obsolescence.

P.S. Is there a specific reason you do not want to use FusedLocationProvider that is part of Google Play Services? I have found it to be simpler and it is supposedly optimized for selected best providers and conserving battery.

Tristan Burnside
  • 2,546
  • 1
  • 16
  • 23
  • One advantage of not using the fused provider is that it doesn't rely on Google Play Services being available. However the Fused Provider is certainly much more feature rich and easier to code against. – pjco Nov 19 '13 at 05:50
  • See edit, this still has issues and it depends exactly what you need it to do but it should help – Tristan Burnside Nov 20 '13 at 12:11
  • another reason i think fusedlocation doesnot support GPS when ever i used fusedlocation with internet off it does not show the location. – Noaman Akram Sep 18 '19 at 22:13
1

My best guess is dump "isBetterLocation" and try without it to see what will happen. Based on those checks (which are rather complicated), I think the mistake is either in "isSignificantlyOlder" or in the last return statement (otherwise you would get the new location, correct?)

Have you debugged it to check if the current logic is correct, and if it is, for what distances?

  • I explained the logic in comments. And it worked perfectly as per the logic(dumping the location only when its better). – Archie.bpgc Nov 18 '13 at 05:28
1

Here is an example to receive location update using Google Play Services

This is MyActivity class

public class MyActivity extends Activity implements
    ConnectionCallbacks, OnConnectionFailedListener {

public static final int PLAY_SERVICES_NOT_AVAILABLE_REQUEST = 9000;
public static final int CONNECTION_FAILED_REQUEST = 1000;

private LocationClient mLocationClient;
private LocationRequest mLocationrequest;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_myactivity);

    LocationManager mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    mLocationClient = new LocationClient(this, this, this);

    boolean isGPSEnabled = mLocationManager
            .isProviderEnabled(LocationManager.GPS_PROVIDER);

    boolean isNetworkEnabled = mLocationManager
            .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

    Toast.makeText(this, "GPS: " + isGPSEnabled, Toast.LENGTH_SHORT).show();
    Toast.makeText(this, "Network: " + isNetworkEnabled, Toast.LENGTH_SHORT)
            .show();

    if (isGooglePlayServicesAvailable()) {
        mLocationClient.connect();
    } else {
        // play services not available
    }
}

private void defineLocationRequest() {
    mLocationrequest = new LocationRequest();
    mLocationrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(5000);
}

private PendingIntent getCallBackIntent() {
    return PendingIntent
            .getService(getApplicationContext(), 0, new Intent(this,
                    MyIntentService.class),
                    PendingIntent.FLAG_UPDATE_CURRENT);
}

private boolean isGooglePlayServicesAvailable() {
    int resultCode = GooglePlayServicesUtil
            .isGooglePlayServicesAvailable(this);

    if (resultCode == ConnectionResult.SUCCESS) {
        Log.d("Car Tracking", "play services available.");
        return true;
    } else {
        Log.d("Car Tracking", "play services not available(resultCode:) "
                + resultCode);
        GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                PLAY_SERVICES_NOT_AVAILABLE_REQUEST).show();
        return false;
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    // TODO Auto-generated method stub
    switch (requestCode) {

    case PLAY_SERVICES_NOT_AVAILABLE_REQUEST:
        if (resultCode == Activity.RESULT_OK) {
            // check again
        }
        break;

    case CONNECTION_FAILED_REQUEST:
        if (resultCode == Activity.RESULT_OK) {
            // try to connect LocationClient Againg
        }

        break;
    }

}

@Override
public void onConnectionFailed(ConnectionResult arg0) {
    // TODO Auto-generated method stub
    if (arg0.hasResolution()) {
        try {
            arg0.startResolutionForResult(this, CONNECTION_FAILED_REQUEST);
        } catch (SendIntentException e) {
            Log.d("TAG",
                    "Exception in resolving connection failed: "
                            + e.toString());
        }

    }
}

@Override
public void onConnected(Bundle arg0) {
    // TODO Auto-generated method stub
    defineLocationRequest();
    mLocationClient.requestLocationUpdates(mLocationrequest,
            getCallBackIntent());

}

@Override
public void onDisconnected() {
    // TODO Auto-generated method stub

}

@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    mLocationClient.removeLocationUpdates(getCallBackIntent());
    super.onDestroy();
}

}

Now, this is MyIntentService Class's onHandleIntent Method.

protected void onHandleIntent(Intent intent) {
    // TODO Auto-generated method stub
    if (intent != null) {

        Bundle extra = intent.getExtras();
        Location location = (Location) extra
                .get(LocationClient.KEY_LOCATION_CHANGED);

}

Here, the location object will give you most recent location update

Also add

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

in your manifest

0

You can use the LocationClient from Google Play Services, its easy to use and proven very efficient. Here is the link to example

Rajesh Batth
  • 1,672
  • 2
  • 19
  • 23
0

Use Fused Location Provider (new feature available since 4.2 - https://developer.android.com/google/play-services/location.html) - it just gets fast current location and sending updates.

Example: http://www.motta-droid.com/2013/11/location-requests-for-your-app-how-to.html

Just run singleton above in a Service and adjust location update params to your needs.

The only issue You should care about - if it can't determine your current location at all. For example, if just GPS location provider available to your device and you're indoors.

Rodion Altshuler
  • 1,713
  • 1
  • 15
  • 31
0

I observed your code..You are updating the location but you are not receiving the updated location information. here is the code how to get the location from a Service

// Send an Intent with an action named "custom-event-name". The Intent sent
// should
// be received by the ReceiverActivity.
private static void sendMessageToActivity(Location l, String msg) {
    Intent intent = new Intent("GPSLocationUpdates");
    // You can also include some extra data.
    intent.putExtra("Status", msg);
    Bundle b = new Bundle();
    b.putParcelable("Location", l);
    intent.putExtra("Location", b);
    LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}

in you main activity or which has to receive the location Info write this code.

LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
            mMessageReceiver, new IntentFilter("GPSLocationUpdates"));

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {         
        Bundle b = intent.getBundleExtra("Location");
        lastKnownLoc = (Location) b.getParcelable("Location");
        if (lastKnownLoc != null) {
            tvLatitude.setText(String.valueOf(lastKnownLoc.getLatitude()));
            tvLongitude
                    .setText(String.valueOf(lastKnownLoc.getLongitude()));              
        }           
    }
};

I hope this will work...

bGorle
  • 1,978
  • 2
  • 22
  • 28
0

I you do not mind waiting for GPS to achieve a first-fix this might help you. The first-fix should only be a matter of seconds if a fix have been found recently.

I have implemented some code that sends callback as soon as there is a first-fix and on locationchange based on GPSTracker from http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial/.

With this implementation you can do:

private GPSTracker gps;
private FirstFixListener firstFixListener;
private LocationUpdateListener locationUpdateListener;

private void startGPS() {
    gps = GPSTracker.getInstance(context);
    // create listeners
    firstFixListener = new MyFirstFixListener();
    locationUpdateListener = new MyLocationUpdateListener();
    // start the gps
    gps.startUsingGPS(firstFixListener, locationUpdateListener);
}

    private void stopGPS() {
        // stop the gps and unregister callbacks
        gps.stopUsingGPS(firstFixListener, locationUpdateListener);
    }

private class MyFirstFixListener implements FirstFixListener {

    @Override
    public void onFirsFixChanged(boolean hasGPSfix) {
        if (hasGPSfix == true) {
            // accurate position
            Location position = gps.getLocation();
        }

    }

}

private class MyLocationUpdateListener implements LocationUpdateListener {

    @Override
    public void onLocationChanged(Location location) {
        // hand you each new location from the GPS
        // you do not need this if you only want to get a single position
    }

}

And here is my implementation of GPSTracker:

public class GPSTracker extends Service implements LocationListener {

private static final String TAG = "GPSTracker";

/**
 * Register to receive callback on first fix status
 * 
 * @author Morten
 * 
 */
public interface FirstFixListener {

    /**
     * Is called whenever gps register a change in first-fix availability
     * This is valuable to prevent sending invalid locations to the server.
     * 
     * @param hasGPSfix
     */
    public void onFirsFixChanged(boolean hasGPSfix);
}

/**
 * Register to receive all location updates
 * 
 * @author Morten
 * 
 */
public interface LocationUpdateListener {
    /**
     * Is called every single time the GPS unit register a new location
     * The location param will never be null, however, it can be outdated if hasGPSfix is not true.
     *  
     * @param location
     */
    public void onLocationChanged(Location location);
}

private Context mContext;

// flag for GPS status
private List<FirstFixListener> firstFixListeners;
private List<LocationUpdateListener> locationUpdateListeners;
boolean isGPSFix = false;
boolean isGPSEnabled = false;
private GPSFixListener gpsListener;

// flag for GPS status
boolean canGetLocation = false;

Location location; // location
double latitude; // latitude
double longitude; // longitude
long mLastLocationMillis;

private boolean logLocationChanges;

// Declaring a Location Manager
protected LocationManager locationManager;

/** removed again as we need multiple instances with different callbacks **/
private static GPSTracker instance;

public static GPSTracker getInstance(Context context) {
    if (instance != null) {
        return instance;
    }
    return instance = new GPSTracker(context);
}

private GPSTracker(Context context) {
    this.mContext = context;
    gpsListener = new GPSFixListener();
    firstFixListeners = new ArrayList<GPSTracker.FirstFixListener>();
    locationUpdateListeners = new ArrayList<GPSTracker.LocationUpdateListener>();
}

public boolean hasGPSFirstFix() {
    return isGPSFix;
}

private void addFirstFixListener(FirstFixListener firstFixListener) {
    this.firstFixListeners.add(firstFixListener);
}

private void addLocationUpdateListener(
        LocationUpdateListener locationUpdateListener) {
    this.locationUpdateListeners.add(locationUpdateListener);
}

private void removeFirstFixListener(FirstFixListener firstFixListener) {
    this.firstFixListeners.remove(firstFixListener);
}

private void removeLocationUpdateListener(
        LocationUpdateListener locationUpdateListener) {
    this.locationUpdateListeners.remove(locationUpdateListener);
}

public void setLogLocationChanges(boolean logLocationChanges) {
    this.logLocationChanges = logLocationChanges;
}

public Location getLocation() {
    return location;
}

private Location startLocationListener() {
    canGetLocation = false;

    try {
        locationManager = (LocationManager) mContext
                .getSystemService(Service.LOCATION_SERVICE);

        // getting GPS status
        isGPSEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);

        if (isGPSEnabled) {
            if (location == null) {
                locationManager.requestLocationUpdates(
                        LocationManager.GPS_PROVIDER, 0, 0, this);
                locationManager.addGpsStatusListener(gpsListener);
                if (locationManager != null) {
                    location = locationManager
                            .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                    }
                }
            }
        } else {
            showSettingsAlert();
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

    return location;
}

public void stopUsingGPS(FirstFixListener firstFixListener,
        LocationUpdateListener locationUpdateListener) {
    if (firstFixListener != null)
        removeFirstFixListener(firstFixListener);
    if (locationUpdateListener != null)
        removeLocationUpdateListener(locationUpdateListener);

    stopUsingGPS();
}

/**
 * Stop using GPS listener Calling this function will stop using GPS in your
 * app
 * */
public void stopUsingGPS() {
    Log.d("DEBUG", "GPS stop");
    if (locationManager != null) {
        locationManager.removeUpdates(GPSTracker.this);
        location = null;

        if (gpsListener != null) {
            locationManager.removeGpsStatusListener(gpsListener);
        }

    }
    isGPSFix = false;
    location = null;
}

public void startUsingGPS(FirstFixListener firstFixListener,
        LocationUpdateListener locationUpdateListener) {
    Log.d("DEBUG", "GPS start");
    if (firstFixListener != null)
        addFirstFixListener(firstFixListener);
    if (locationUpdateListener != null)
        addLocationUpdateListener(locationUpdateListener);

    startLocationListener();
}

/**
 * Function to get latitude
 * */
public double getLatitude() {
    if (location != null) {
        latitude = location.getLatitude();
    } else {
        Log.e("GPSTracker", "getLatitude location is null");
    }

    // return latitude
    return latitude;
}

/**
 * Function to get longitude
 * */
public double getLongitude() {
    if (location != null) {
        longitude = location.getLongitude();
    } else {
        Log.e("GPSTracker", "getLongitude location is null");
    }

    // return longitude
    return longitude;
}

/**
 * Function to check GPS/wifi enabled
 * 
 * @return boolean
 * */
public boolean canGetLocation() {
    return this.canGetLocation;
}

/**
 * Function to show settings alert dialog On pressing Settings button will
 * lauch Settings Options
 * */
public void showSettingsAlert() {
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

    // Setting Dialog Title
    alertDialog.setTitle("GPS settings");

    // Setting Dialog Message
    alertDialog
            .setMessage("GPS is not enabled. Do you want to go to settings menu?");

    // On pressing Settings button
    alertDialog.setPositiveButton("Settings",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent = new Intent(
                            Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    mContext.startActivity(intent);
                }
            });

    // on pressing cancel button
    alertDialog.setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

    // Showing Alert Message
    alertDialog.show();
}

@Override
public void onLocationChanged(Location location) {
    if ( location == null)
        return;

    this.location = location;



    mLastLocationMillis = SystemClock.elapsedRealtime();
    canGetLocation = true;
    if (isGPSFix) {


        if (locationUpdateListeners != null) {
            for (LocationUpdateListener listener : locationUpdateListeners) {
                listener.onLocationChanged(location);
            }
        }
    }

}

@Override
public void onProviderDisabled(String provider) {
    canGetLocation = false;
}

@Override
public void onProviderEnabled(String provider) {

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

private boolean wasGPSFix = false;

// http://stackoverflow.com/questions/2021176/how-can-i-check-the-current-status-of-the-gps-receiver
// answer from soundmaven
private class GPSFixListener implements GpsStatus.Listener {
    public void onGpsStatusChanged(int event) {
        switch (event) {
        case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
            isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;

            if (isGPSFix != wasGPSFix) { // only notify on changes
                wasGPSFix = isGPSFix;
                for (FirstFixListener listener : firstFixListeners) {
                    listener.onFirsFixChanged(isGPSFix);
                }
            }

            break;
        case GpsStatus.GPS_EVENT_FIRST_FIX:
            // Do something.



            break;
        }
    }
}
}
cYrixmorten
  • 7,110
  • 3
  • 25
  • 33