diff options
Diffstat (limited to 'main/src/cgeo/geocaching/cgGeo.java')
| -rw-r--r-- | main/src/cgeo/geocaching/cgGeo.java | 276 |
1 files changed, 90 insertions, 186 deletions
diff --git a/main/src/cgeo/geocaching/cgGeo.java b/main/src/cgeo/geocaching/cgGeo.java index 3384e04..19ffdf2 100644 --- a/main/src/cgeo/geocaching/cgGeo.java +++ b/main/src/cgeo/geocaching/cgGeo.java @@ -17,166 +17,116 @@ import java.util.Iterator; public class cgGeo { - private LocationManager geoManager = null; - private cgUpdateLoc geoUpdate = null; - private cgeoGeoListener geoNetListener = null; - private cgeoGeoListener geoGpsListener = null; - private cgeoGpsStatusListener geoGpsStatusListener = null; + private static final String LAST_LOCATION_PSEUDO_PROVIDER = "last"; + private final LocationManager geoManager = (LocationManager) cgeoapplication.getInstance().getSystemService(Context.LOCATION_SERVICE); + private UpdateLocationCallback updateLocationCallback = null; + private final AbstractLocationListener networkListener = new NetworkLocationListener(); + private final AbstractLocationListener gpsListener = new GpsLocationListener(); + private final GpsStatusListener gpsStatusListener = new GpsStatusListener(); private Location locGps = null; private Location locNet = null; private long locGpsLast = 0L; public Location location = null; public LocationProviderType locationProvider = LocationProviderType.LAST; public Geopoint coordsNow = null; - public Geopoint coordsBefore = null; public Double altitudeNow = null; public Float bearingNow = null; public Float speedNow = null; public Float accuracyNow = null; - public Integer satellitesVisible = null; - public Integer satellitesFixed = null; + public int satellitesVisible = 0; + public int satellitesFixed = 0; - public cgGeo(cgUpdateLoc geoUpdateIn) { - geoUpdate = geoUpdateIn; + public cgGeo() { + restoreLastLocation(); - geoNetListener = new cgeoGeoListener(); - geoNetListener.setProvider(LocationManager.NETWORK_PROVIDER); + geoManager.addGpsStatusListener(gpsStatusListener); - geoGpsListener = new cgeoGeoListener(); - geoGpsListener.setProvider(LocationManager.GPS_PROVIDER); + for (AbstractLocationListener listener : new AbstractLocationListener[] { networkListener, gpsListener }) { + try { + geoManager.requestLocationUpdates(listener.locationProvider, 0, 0, listener); + } catch (Exception e) { + Log.w(Settings.tag, "There is no location provider " + listener.locationProvider); + } + } + } - geoGpsStatusListener = new cgeoGpsStatusListener(); + public void closeGeo() { + geoManager.removeUpdates(networkListener); + geoManager.removeUpdates(gpsListener); + geoManager.removeGpsStatusListener(gpsStatusListener); + } - initGeo(); + public void replaceUpdate(UpdateLocationCallback callback) { + updateLocationCallback = callback; + fireLocationCallback(); } - private void initGeo() { - location = null; - locationProvider = LocationProviderType.LAST; - coordsNow = null; - altitudeNow = null; - bearingNow = null; - speedNow = null; - accuracyNow = null; - satellitesVisible = 0; - satellitesFixed = 0; - - if (geoManager == null) { - geoManager = (LocationManager) cgeoapplication.getInstance().getSystemService(Context.LOCATION_SERVICE); + private void fireLocationCallback() { + if (updateLocationCallback != null) { + updateLocationCallback.updateLocation(this); } + } - lastLoc(); - - geoNetListener.setProvider(LocationManager.NETWORK_PROVIDER); - geoGpsListener.setProvider(LocationManager.GPS_PROVIDER); - geoManager.addGpsStatusListener(geoGpsStatusListener); + private abstract class AbstractLocationListener implements LocationListener { + private final String locationProvider; - try { - geoManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, geoNetListener); - } catch (Exception e) { - Log.w(Settings.tag, "There is no NETWORK location provider"); + protected AbstractLocationListener(String provider) { + this.locationProvider = provider; } - try { - geoManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, geoGpsListener); - } catch (Exception e) { - Log.w(Settings.tag, "There is no GPS location provider"); + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + // nothing } - } - public void closeGeo() { - if (geoManager != null && geoNetListener != null) { - geoManager.removeUpdates(geoNetListener); - } - if (geoManager != null && geoGpsListener != null) { - geoManager.removeUpdates(geoGpsListener); - } - if (geoManager != null) { - geoManager.removeGpsStatusListener(geoGpsStatusListener); + @Override + public void onProviderDisabled(String provider) { + if (provider.equals(locationProvider)) { + geoManager.removeUpdates(this); + } } - } - public void replaceUpdate(cgUpdateLoc geoUpdateIn) { - geoUpdate = geoUpdateIn; - - if (geoUpdate != null) { - geoUpdate.updateLoc(this); + @Override + public void onProviderEnabled(String provider) { + // nothing } } - public class cgeoGeoListener implements LocationListener { - - public String active = null; + private final class GpsLocationListener extends AbstractLocationListener { - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - // nothing + public GpsLocationListener() { + super(LocationManager.GPS_PROVIDER); } @Override public void onLocationChanged(Location location) { - if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) { - locGps = location; - locGpsLast = System.currentTimeMillis(); - } else if (location.getProvider().equals(LocationManager.NETWORK_PROVIDER)) { - locNet = location; - } - + locGps = location; + locGpsLast = System.currentTimeMillis(); selectBest(location.getProvider()); } + } - @Override - public void onProviderDisabled(String provider) { - if (provider.equals(LocationManager.NETWORK_PROVIDER)) { - if (geoManager != null && geoNetListener != null) { - geoManager.removeUpdates(geoNetListener); - } - } else if (provider.equals(LocationManager.GPS_PROVIDER)) { - if (geoManager != null && geoGpsListener != null) { - geoManager.removeUpdates(geoGpsListener); - } - } + private final class NetworkLocationListener extends AbstractLocationListener { + + protected NetworkLocationListener() { + super(LocationManager.NETWORK_PROVIDER); } @Override - public void onProviderEnabled(String provider) { - if (provider.equals(LocationManager.NETWORK_PROVIDER)) { - if (geoNetListener == null) { - geoNetListener = new cgeoGeoListener(); - } - geoNetListener.setProvider(LocationManager.NETWORK_PROVIDER); - } else if (provider.equals(LocationManager.GPS_PROVIDER)) { - if (geoGpsListener == null) { - geoGpsListener = new cgeoGeoListener(); - } - geoGpsListener.setProvider(LocationManager.GPS_PROVIDER); - } + public void onLocationChanged(Location location) { + locNet = location; + selectBest(location.getProvider()); } - public void setProvider(String provider) { - if (provider.equals(LocationManager.GPS_PROVIDER)) { - if (geoManager != null && geoManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { - active = provider; - } else { - active = null; - } - } else if (provider.equals(LocationManager.NETWORK_PROVIDER)) { - if (geoManager != null && geoManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { - active = provider; - } else { - active = null; - } - } - } } - public class cgeoGpsStatusListener implements GpsStatus.Listener { + private final class GpsStatusListener implements GpsStatus.Listener { @Override public void onGpsStatusChanged(int event) { if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS) { - GpsStatus status = geoManager.getGpsStatus(null); - Iterator<GpsSatellite> statusIterator = status.getSatellites().iterator(); + final GpsStatus status = geoManager.getGpsStatus(null); + final Iterator<GpsSatellite> statusIterator = status.getSatellites().iterator(); int satellites = 0; int fixed = 0; @@ -187,23 +137,14 @@ public class cgGeo { fixed++; } satellites++; - - /* - * satellite signal strength - * if (sat.usedInFix()) { - * Log.d(Settings.tag, "Sat #" + satellites + ": " + sat.getSnr() + " FIX"); - * } else { - * Log.d(Settings.tag, "Sat #" + satellites + ": " + sat.getSnr()); - * } - */ } boolean changed = false; - if (satellitesVisible == null || satellites != satellitesVisible) { + if (satellites != satellitesVisible) { satellitesVisible = satellites; changed = true; } - if (satellitesFixed == null || fixed != satellitesFixed) { + if (fixed != satellitesFixed) { satellitesFixed = fixed; changed = true; } @@ -215,36 +156,23 @@ public class cgGeo { } } - private void selectBest(String initProvider) { - if (locNet == null && locGps != null) { // we have only GPS - assign(locGps); - return; - } - + private void selectBest(final String signallingProvider) { if (locNet != null && locGps == null) { // we have only NET assign(locNet); - return; } - - if (satellitesFixed > 0) { // GPS seems to be fixed + else if ((locNet == null && locGps != null) // we have only GPS + || (satellitesFixed > 0) // GPS seems to be fixed + || (signallingProvider != null && signallingProvider.equals(LocationManager.GPS_PROVIDER)) // we have new location from GPS + || locGpsLast > (System.currentTimeMillis() - 30 * 1000) // GPS was working in last 30 seconds + ) { assign(locGps); - return; } - - if (initProvider != null && initProvider.equals(LocationManager.GPS_PROVIDER)) { // we have new location from GPS - assign(locGps); - return; + else { + assign(locNet); // nothing else, using NET } - - if (locGpsLast > (System.currentTimeMillis() - 30 * 1000)) { // GPS was working in last 30 seconds - assign(locGps); - return; - } - - assign(locNet); // nothing else, using NET } - private void assign(final Geopoint coords) { + private void assignLastLocation(final Geopoint coords) { if (coords == null) { return; } @@ -256,12 +184,10 @@ public class cgGeo { speedNow = 0f; accuracyNow = 999f; - if (geoUpdate != null) { - geoUpdate.updateLoc(this); - } + fireLocationCallback(); } - private void assign(Location loc) { + private void assign(final Location loc) { if (loc == null) { locationProvider = LocationProviderType.LAST; return; @@ -269,12 +195,12 @@ public class cgGeo { location = loc; - String provider = location.getProvider(); + final String provider = location.getProvider(); if (provider.equals(LocationManager.GPS_PROVIDER)) { locationProvider = LocationProviderType.GPS; } else if (provider.equals(LocationManager.NETWORK_PROVIDER)) { locationProvider = LocationProviderType.NETWORK; - } else if (provider.equalsIgnoreCase("last")) { + } else if (provider.equalsIgnoreCase(LAST_LOCATION_PSEUDO_PROVIDER)) { locationProvider = LocationProviderType.LAST; } @@ -302,49 +228,27 @@ public class cgGeo { accuracyNow = 999f; } - if (locationProvider == LocationProviderType.GPS) { - // save travelled distance only when location is from GPS - if (coordsBefore != null) { - final float dst = coordsBefore.distanceTo(coordsNow); - - if (dst > 0.005) { - coordsBefore = coordsNow; - } - } else if (coordsBefore == null) { // values aren't initialized - coordsBefore = coordsNow; - } - } - - if (geoUpdate != null) { - geoUpdate.updateLoc(this); - } + fireLocationCallback(); if (locationProvider == LocationProviderType.GPS || locationProvider == LocationProviderType.NETWORK) { Go4Cache.signalCoordinates(coordsNow); } } - public void lastLoc() { - assign(cgeoapplication.getInstance().getLastCoords()); - - Location lastGps = geoManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); - - if (lastGps != null) { - lastGps.setProvider("last"); - assign(lastGps); + private void restoreLastLocation() { + // restore from last location (stored by app) + assignLastLocation(cgeoapplication.getInstance().getLastCoords()); - Log.i(Settings.tag, "Using last location from GPS"); - return; - } + // restore from last location (stored by device sensors) + for (String provider : new String[] { LocationManager.GPS_PROVIDER, LocationManager.NETWORK_PROVIDER }) { + final Location lastLocation = geoManager.getLastKnownLocation(provider); + if (lastLocation != null) { + lastLocation.setProvider(LAST_LOCATION_PSEUDO_PROVIDER); + assign(lastLocation); - Location lastGsm = geoManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); - - if (lastGsm != null) { - lastGsm.setProvider("last"); - assign(lastGsm); - - Log.i(Settings.tag, "Using last location from NETWORK"); - return; + Log.i(Settings.tag, "Using last location from " + provider); + break; + } } } } |
