Back to project page AQUArinthia.
The source code is released under:
GNU General Public License
If you think the Android project AQUArinthia listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package at.theengine.android.bestlocation; //from ww w .ja va 2 s.c o m import java.util.Date; import android.content.Context; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; public class BestLocationProvider { public enum LocationType { GPS, CELL, UNKNOWN } private static final String TAG = "BestLocationProvider"; private static final int TOO_OLD_LOCATION_DELTA = 1000 * 60 * 2; private Context mContext; private LocationManager mLocationMgrCell; private LocationManager mLocationMgrGPS; private LocationListener mLocationListener; private Location mLocation; private Timeout mGPSTimeout; private Timeout mCellTimeout; private BestLocationListener mListener; //config private boolean mUseGPSLocation; private boolean mUseCellLocation; private long mMaxGPSLocationUpdateTimespan; private long mMaxCellLocationUpdateTimespan; private long mMinTime; private float mMinDinstace; public BestLocationProvider(Context context, boolean useGPSLocation, boolean useCellLocation, long maxGPSLocationUpdateTimespan, long maxCellLocationUpdateTimespan, long minTime, float minDistance){ this.mContext = context; this.mUseGPSLocation = useGPSLocation; this.mUseCellLocation = useCellLocation; this.mMaxGPSLocationUpdateTimespan = maxGPSLocationUpdateTimespan; this.mMaxCellLocationUpdateTimespan = maxCellLocationUpdateTimespan; this.mMinTime = minTime; this.mMinDinstace = minDistance; initLocationListener(); initLocationManager(); } public void startLocationUpdatesWithListener(BestLocationListener listener){ this.mListener = listener; Location lastKnownLocationCell = null; Location lastKnownLocationGPS = null; if(mLocationMgrCell != null){ mLocationMgrCell.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, mMinTime, mMinDinstace, mLocationListener); if(this.mMaxCellLocationUpdateTimespan > 0){ mCellTimeout = new Timeout(); mCellTimeout.setTimeout(this.mMaxCellLocationUpdateTimespan); mCellTimeout.setLocationType(LocationType.CELL); mCellTimeout.execute(); } lastKnownLocationCell = mLocationMgrCell.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } if(mLocationMgrGPS != null){ mLocationMgrGPS.requestLocationUpdates(LocationManager.GPS_PROVIDER, mMinTime, mMinDinstace, mLocationListener); if(this.mMaxGPSLocationUpdateTimespan > 0){ mGPSTimeout = new Timeout(); mGPSTimeout.setTimeout(this.mMaxGPSLocationUpdateTimespan); mGPSTimeout.setLocationType(LocationType.GPS); mGPSTimeout.execute(); } lastKnownLocationGPS = mLocationMgrGPS.getLastKnownLocation(LocationManager.GPS_PROVIDER); } if(lastKnownLocationCell != null && isBetterLocation(lastKnownLocationCell, mLocation)){ updateLocation(lastKnownLocationCell, LocationType.CELL, false); } if(lastKnownLocationGPS != null && isBetterLocation(lastKnownLocationGPS, mLocation)){ updateLocation(lastKnownLocationGPS, LocationType.GPS, false); } } public void stopLocationUpdates(){ if(mLocationMgrCell != null){ mLocationMgrCell.removeUpdates(mLocationListener); } if(mLocationMgrGPS != null){ mLocationMgrGPS.removeUpdates(mLocationListener); } //remove timeout threads if(mGPSTimeout != null){ try { mGPSTimeout.cancel(true); } catch(Exception e) { } mGPSTimeout = null; } if(mCellTimeout != null){ try { mCellTimeout.cancel(true); } catch(Exception e) { } mCellTimeout = null; } } private void restartTimeout(LocationType type){ if(type == LocationType.GPS){ if(mGPSTimeout != null){ try { mGPSTimeout.cancel(true); } catch(Exception e) { } mGPSTimeout = new Timeout(); mGPSTimeout.setTimeout(this.mMaxGPSLocationUpdateTimespan); mGPSTimeout.setLocationType(LocationType.GPS); mGPSTimeout.execute(); } } if(type == LocationType.CELL){ if(mCellTimeout != null){ try { mCellTimeout.cancel(true); } catch(Exception e) { } mCellTimeout = new Timeout(); mCellTimeout.setTimeout(this.mMaxCellLocationUpdateTimespan); mCellTimeout.setLocationType(LocationType.CELL); mCellTimeout.execute(); } } } private void updateLocation(Location location, LocationType type, boolean isFresh){ mLocation = location; mListener.onLocationUpdate(location, type, isFresh); } private void initLocationManager(){ if(mUseCellLocation){ mLocationMgrCell = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); if(!mLocationMgrCell.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){ mLocationMgrCell = null; } } if(mUseGPSLocation){ mLocationMgrGPS = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); if(!mLocationMgrGPS.isProviderEnabled(LocationManager.GPS_PROVIDER)){ mLocationMgrGPS = null; } } } private void initLocationListener(){ mLocationListener = new LocationListener() { public void onLocationChanged(Location location) { Log.i(TAG, "onLocationChanged: " + locationToString(location)); if(isBetterLocation(location, mLocation)){ updateLocation(location, providerToLocationType(location.getProvider()), true); if(providerToLocationType(location.getProvider()) == LocationType.CELL){ if(mCellTimeout != null){ mCellTimeout.resetTimeout(); } } if(providerToLocationType(location.getProvider()) == LocationType.GPS){ if(mGPSTimeout != null){ mGPSTimeout.resetTimeout(); } } Log.d(TAG, "onLocationChanged NEW BEST LOCATION: " + locationToString(mLocation)); } } public void onStatusChanged(String provider, int status, Bundle extras) { mListener.onStatusChanged(provider, status, extras); } public void onProviderEnabled(String provider) { mListener.onProviderEnabled(provider); } public void onProviderDisabled(String provider) { mListener.onProviderDisabled(provider); } }; } private LocationType providerToLocationType(String provider){ if(provider.equals("gps")){ return LocationType.GPS; } else if(provider.equals("network")){ return LocationType.CELL; } else { Log.w(TAG, "providerToLocationType Unknown Provider: " + provider); return LocationType.UNKNOWN; } } public String locationToString(Location l){ StringBuffer sb = new StringBuffer(); sb.append("PROVIDER: "); sb.append(l.getProvider()); sb.append(" - LAT: "); sb.append(l.getLatitude()); sb.append(" - LON: "); sb.append(l.getLongitude()); sb.append(" - BEARING: "); sb.append(l.getBearing()); sb.append(" - ALT: "); sb.append(l.getAltitude()); sb.append(" - SPEED: "); sb.append(l.getSpeed()); sb.append(" - TIME: "); sb.append(l.getTime()); sb.append(" - ACC: "); sb.append(l.getAccuracy()); return sb.toString(); } 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 > TOO_OLD_LOCATION_DELTA; boolean isSignificantlyOlder = timeDelta < -TOO_OLD_LOCATION_DELTA; 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()); // Determine location quality using a combination of timeliness and accuracy if (isMoreAccurate) { return true; } else if (isNewer && !isLessAccurate) { return true; } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { 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); } //timeout threads private class Timeout extends AsyncTask<Void, Void, Void> { private LocationType mLocationType; private long mTimeout; private long mStartTime; public void setLocationType(LocationType locationtype){ mLocationType = locationtype; } public void setTimeout(long timeout){ mTimeout = timeout; } public void resetTimeout(){ mStartTime = new Date().getTime(); } @Override protected Void doInBackground(Void... params) { resetTimeout(); try { while(new Date().getTime() < mStartTime + mTimeout){ Thread.sleep(1000); } } catch (InterruptedException e) { Log.e(TAG, "Timeout: Exception in doInBackground: " + e.getMessage()); } return null; } @Override protected void onPostExecute(Void result) { mListener.onLocationUpdateTimeoutExceeded(mLocationType); restartTimeout(mLocationType); } } }