/* Copyright 2012 Nik Cain nik@showmehills.com This file is part of ShowMeHills. ShowMeHills is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ShowMeHills is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with ShowMeHills. If not, see <http://www.gnu.org/licenses/>. This source originated from mixare, another GPL project. */ package com.showmehills; import java.util.ArrayList; import java.util.List; import android.location.Location; import android.location.LocationManager; import android.location.Criteria; public class RapidGPSLock { private IShowMeHillsActivity mixContext; private LocationManager mLocationManager; private Location curLoc; private String bestLocationProvider; private Location locationAtLastDownload; private LocationFinderState state; private final LocationObserver lob; private List<LocationResolver> locationResolvers; public enum LocationFinderState { Active, // Providing Location Information Inactive, // No-Active Confused // Same problem in internal state } public RapidGPSLock(IShowMeHillsActivity mixContext) { this.mixContext = mixContext; this.lob = new LocationObserver(this); this.state = LocationFinderState.Inactive; this.locationResolvers = new ArrayList<LocationResolver>(); } public void findLocation() { if (mLocationManager == null) return; // fallback for the case where GPS and network providers are disabled Location hardFix = new Location("reverseGeocoded"); // Frangart, Eppan, Bozen, Italy hardFix.setLatitude(46.480302); hardFix.setLongitude(11.296005); hardFix.setAltitude(300); try { requestBestLocationUpdates(); //temporary set the current location, until a good provider is found curLoc = mLocationManager.getLastKnownLocation(mLocationManager.getBestProvider(new Criteria(), true)); } catch (Exception ex2) { // ex2.printStackTrace(); curLoc = hardFix; } } public void locationCallback(String provider) { if (mLocationManager == null) return; Location foundLocation = mLocationManager.getLastKnownLocation(provider); if (bestLocationProvider != null) { Location bestLocation = mLocationManager.getLastKnownLocation(bestLocationProvider); if (bestLocation != null && foundLocation.getAccuracy() < bestLocation.getAccuracy()) { curLoc = foundLocation; bestLocationProvider = provider; mixContext.UpdateMarkers(); } } else { curLoc = foundLocation; bestLocationProvider = provider; mixContext.UpdateMarkers(); } setLocationAtLastDownload(curLoc); } private void requestBestLocationUpdates() { if (mLocationManager == null) return; for(LocationResolver locationResolver: locationResolvers) { mLocationManager.requestLocationUpdates(locationResolver.provider, 0, 0, locationResolver); } /*for (String p : mLocationManager.getAllProviders()) { if(mLocationManager.isProviderEnabled(p)) { LocationResolver lr = new LocationResolver(mLocationManager, p, this); Log.d("showmehills", "adding resolver (" + p + " "+ lr.hashCode()+")"); locationResolvers.add(lr); mLocationManager.requestLocationUpdates(p, 0, 0, lr); } }*/ } public void setLocationAtLastDownload(Location locationAtLastDownload) { this.locationAtLastDownload = locationAtLastDownload; } public void setPosition(Location location) { synchronized (curLoc) { curLoc = location; } Location lastLoc = getLocationAtLastDownload(); if (lastLoc == null) { setLocationAtLastDownload(location); } } public Location getCurrentLocation() { if (curLoc == null) { return null; //throw new RuntimeException("No GPS Found"); } synchronized (curLoc) { return curLoc; } } public Location getLocationAtLastDownload() { return locationAtLastDownload; } public void switchOn() { if (!LocationFinderState.Active.equals(state)) { mLocationManager = mixContext.GetLocationManager(); locationResolvers.clear(); for (String p : mLocationManager.getAllProviders()) { if(mLocationManager.isProviderEnabled(p)) { LocationResolver lr = new LocationResolver(mLocationManager, p, this); locationResolvers.add(lr); } } state = LocationFinderState.Confused; } } public void switchOff() { if (mLocationManager != null) { mLocationManager.removeUpdates(getObserver()); state = LocationFinderState.Inactive; } } public LocationFinderState getStatus() { return state; } private synchronized LocationObserver getObserver() { return lob; } public void RenewLocation() { if (mLocationManager == null) return; if(bestLocationProvider != null) { //remove all location updates for(LocationResolver locationResolver: locationResolvers) { mLocationManager.removeUpdates(locationResolver); } mLocationManager.removeUpdates(getObserver()); state=LocationFinderState.Confused; requestBestLocationUpdates(); state=LocationFinderState.Active; } else { //no location found } } }