package org.r3pek.pharmacies.utils; import java.util.LinkedList; import android.content.Context; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.util.Log; import com.google.android.maps.GeoPoint; public class Positioner implements LocationListener { private Location currentLocation; private GeoPoint currentGeoPoint; private float currentAccuracy; private LinkedList toNotify; private LocationManager locationManager; private boolean isUpdating; private boolean hadGPSFix; private boolean isFixedLocation; private boolean isGPSFix; public Positioner(Context context) { toNotify = new LinkedList(); locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); isUpdating = false; hadGPSFix = false; isFixedLocation = false; isGPSFix = false; initLocation(); requestUpdates(); } private void initLocation() { if (!isLocalizationActive()) return; Location loc_net = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); Location loc_gps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); Location loc = loc_gps == null ? loc_net : loc_gps; if (loc == null) return; currentLocation = loc; currentGeoPoint = new GeoPoint((int)(loc.getLatitude() * 1E6), (int)(loc.getLongitude() * 1E6)); currentAccuracy = loc.getAccuracy(); notifyAllClients(); } private String getBestLocationProvider() { if (!isLocalizationActive()) return LocationManager.GPS_PROVIDER; else if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) return LocationManager.GPS_PROVIDER; else return LocationManager.NETWORK_PROVIDER; } public void requestUpdates() { if (isUpdating) return; Log.d("Positioner", "Enabling location Updates"); if (getBestLocationProvider().equals(LocationManager.GPS_PROVIDER) && !hadGPSFix) locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); locationManager.requestLocationUpdates(getBestLocationProvider(), 0, 0, this); isUpdating = true; } public void cancelUpdates() { if (!isUpdating) return; Log.d("Positioner", "Disabling location Updates"); locationManager.removeUpdates(this); isUpdating = false; } public boolean isLocalizationActive() { return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); } public void registerNotification(OnPositionChangeListener object) { Log.d("Positioner", "Adding notification " + object.getClass().getCanonicalName()); toNotify.add(object); } public void unregisterNotification(OnPositionChangeListener object) { Log.d("Positioner", "Removing notification " + object.getClass().getCanonicalName()); toNotify.remove(object); } public Location getLastLocation() { return currentLocation; } public GeoPoint getLastGeoPoint() { return currentGeoPoint; } public float getLastAccuracy() { return currentAccuracy; } @Override public synchronized void onLocationChanged(Location location) { Log.d("Positioner", "New location arrived"); /* If we already have a GPS fix, discard Network locations */ if (hadGPSFix && location.getProvider().equals(LocationManager.NETWORK_PROVIDER)) return; /* Save location */ currentLocation = location; currentGeoPoint = new GeoPoint((int)(location.getLatitude() * 1E6), (int)(location.getLongitude() * 1E6)); currentAccuracy = location.getAccuracy(); /* Did it come from GPS or Network? */ if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) { hadGPSFix = true; isGPSFix = true; } else { hadGPSFix = false; isGPSFix = false; } /* Notify the clients if there is any */ if (toNotify.size() > 0) notifyAllClients(); } @Override public void onProviderDisabled(String provider) { } @Override public void onProviderEnabled(String provider) { Log.d("Positioner", "Provider enabled: " + provider); initLocation(); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } private synchronized void notifyAllClients() { Log.d("Positioner", "Notifying clients"); for (OnPositionChangeListener l : toNotify) l.onLocationChange(currentGeoPoint, currentAccuracy); } public synchronized void setFixedLocation(Location location) { if (!isFixedLocation) { cancelUpdates(); isFixedLocation = true; } onLocationChanged(location); } public void cancelFixedLocation() { if (!isFixedLocation) return; hadGPSFix = false; requestUpdates(); isFixedLocation = false; } public boolean isFixedLocation() { return isFixedLocation; } public boolean isGPSFix() { return isGPSFix; } }