Created
June 19, 2013 10:32
-
-
Save scruffyfox/5813346 to your computer and use it in GitHub Desktop.
Location helper class which uses a series of different listeners to determine the user's current location as accurately as possible.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * @brief x lib is the library which includes the commonly used functions in 3 Sided Cube Android applications | |
| * | |
| * @author Callum Taylor | |
| **/ | |
| package in.lib.helper; | |
| import java.util.List; | |
| import android.content.Context; | |
| import android.location.Location; | |
| import android.location.LocationListener; | |
| import android.location.LocationManager; | |
| import android.os.Bundle; | |
| import android.os.Handler; | |
| import android.provider.Settings; | |
| /** | |
| * @brief This class is used to fetch the user's current location using either | |
| * cached location (if available) or requests it using the | |
| * LocationListener if not | |
| */ | |
| public class LocationHelper implements LocationListener | |
| { | |
| /** | |
| * Message ID: Used when a provider has been disabled | |
| */ | |
| public static final int MESSAGE_PROVIDER_DISABLED = 0; | |
| /** | |
| * Message ID: Used when the search has timed out | |
| */ | |
| public static final int MESSAGE_TIMEOUT = 1; | |
| /** | |
| * Message ID: Used when the user cancels the request | |
| */ | |
| public static final int MESSAGE_FORCED_CANCEL = 2; | |
| private final Context mContext; | |
| private final LocationManager mLocationManager; | |
| private final long mTimeout = 0; | |
| private LocationResponse mCallback = null; | |
| private Accuracy mAccuracy = Accuracy.FINE; | |
| private final Handler mTimeoutHandler = new Handler(); | |
| private float mAccuracyFloat = 30.0f; | |
| private final Runnable mTimeoutRunnable = new Runnable() | |
| { | |
| @Override public void run() | |
| { | |
| mTimeoutHandler.removeCallbacks(mTimeoutRunnable); | |
| mLocationManager.removeUpdates(LocationHelper.this); | |
| if (mCallback != null) | |
| { | |
| mCallback.onLocationFailed("Timeout", MESSAGE_TIMEOUT); | |
| mCallback.onTimeout(); | |
| } | |
| }; | |
| }; | |
| /** | |
| * Determines the accuracy of the fetch | |
| */ | |
| public enum Accuracy | |
| { | |
| /** | |
| * Get the location as close to the real point as possible | |
| */ | |
| FINE, | |
| /** | |
| * Get the location by any means | |
| */ | |
| COARSE; | |
| } | |
| /** | |
| * Default Constructor | |
| * | |
| * @param context | |
| * The application/activity context to use | |
| */ | |
| public LocationHelper(Context context) | |
| { | |
| mContext = context; | |
| mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); | |
| } | |
| /** | |
| * Cancels the request | |
| */ | |
| public void cancelRequest() | |
| { | |
| mTimeoutHandler.removeCallbacks(mTimeoutRunnable); | |
| mLocationManager.removeUpdates(this); | |
| if (mCallback != null) | |
| { | |
| mCallback.onLocationFailed("Canceld", MESSAGE_FORCED_CANCEL); | |
| } | |
| } | |
| /** | |
| * Sets the desired accuracy for the fetch | |
| * | |
| * @param accuracy | |
| * The new accuracy | |
| */ | |
| public void setAccuracy(float accuracy) | |
| { | |
| mAccuracyFloat = accuracy; | |
| } | |
| /** | |
| * Gets the current set desired accuracy for a fetch | |
| * | |
| * @return The accuracy in meters | |
| */ | |
| public float getAccuracy() | |
| { | |
| return mAccuracyFloat; | |
| } | |
| /** | |
| * Fetches the location using Fine accuracy. Note: if the response returns | |
| * location fetch failed, use the helper to get the cached location, then | |
| * finally fail if that is null | |
| * | |
| * @param timeout | |
| * The time out for the request in MS | |
| * @param callback | |
| * The callback for the request | |
| */ | |
| public void fetchLocation(long timeout, LocationResponse callback) | |
| { | |
| fetchLocation(timeout, Accuracy.FINE, callback); | |
| } | |
| /** | |
| * Fetches the location | |
| * | |
| * @param timeout | |
| * The time out for the request in MS | |
| * @param accuracy | |
| * The accuracy of the fetch | |
| * @param callback | |
| * The callback for the request | |
| */ | |
| public void fetchLocation(long timeout, Accuracy accuracy, LocationResponse callback) | |
| { | |
| mCallback = callback; | |
| mCallback.onRequest(); | |
| mAccuracy = accuracy; | |
| Location userLocation = null; | |
| // Try to get the cache location first | |
| userLocation = getCachedLocation(); | |
| // if (userLocation == null) | |
| { | |
| if (timeout > 0) | |
| { | |
| mTimeoutHandler.postDelayed(mTimeoutRunnable, timeout); | |
| } | |
| try | |
| { | |
| mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); | |
| } | |
| catch (Exception e) | |
| { | |
| e.printStackTrace(); | |
| } | |
| try | |
| { | |
| mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); | |
| } | |
| catch (Exception e) | |
| { | |
| e.printStackTrace(); | |
| } | |
| try | |
| { | |
| mLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, this); | |
| } | |
| catch (Exception e) | |
| { | |
| e.printStackTrace(); | |
| } | |
| } | |
| } | |
| /** | |
| * Gets the cached location | |
| * | |
| * @return The location, or null if one was not retrieved | |
| */ | |
| public Location getCachedLocation() | |
| { | |
| List<String> providers = mLocationManager.getProviders(true); | |
| Location l = null; | |
| for (int i = providers.size() - 1; i >= 0; i--) | |
| { | |
| Location loc = mLocationManager.getLastKnownLocation(providers.get(i)); | |
| if (l == null || (loc != null && loc.getAccuracy() < l.getAccuracy())) | |
| { | |
| l = loc; | |
| } | |
| } | |
| return l; | |
| } | |
| private boolean hasAquired = false; | |
| @Override public void onLocationChanged(Location location) | |
| { | |
| if (location != null) | |
| { | |
| if (mCallback != null) | |
| { | |
| mCallback.onLocationChanged(location); | |
| if (mAccuracy == Accuracy.FINE && (!location.hasAccuracy() || location.getAccuracy() > mAccuracyFloat)) | |
| return; | |
| if (!hasAquired) | |
| { | |
| mTimeoutHandler.removeCallbacks(mTimeoutRunnable); | |
| mLocationManager.removeUpdates(this); | |
| mCallback.onLocationAquired(location); | |
| hasAquired = true; | |
| } | |
| } | |
| } | |
| } | |
| public void stopFetch() | |
| { | |
| mTimeoutHandler.removeCallbacks(mTimeoutRunnable); | |
| mLocationManager.removeUpdates(this); | |
| } | |
| @Override public void onProviderDisabled(String provider) | |
| { | |
| List<String> providers = mLocationManager.getProviders(true); | |
| boolean allOn = false; | |
| for (int i = providers.size() - 1; i >= 0; i--) | |
| { | |
| allOn |= Settings.Secure.isLocationProviderEnabled(mContext.getContentResolver(), providers.get(i)); | |
| } | |
| if (!allOn) | |
| { | |
| mTimeoutHandler.removeCallbacks(mTimeoutRunnable); | |
| mLocationManager.removeUpdates(this); | |
| if (mCallback != null) | |
| { | |
| mCallback.onLocationFailed("All providers disabled", MESSAGE_PROVIDER_DISABLED); | |
| } | |
| } | |
| } | |
| @Override public void onProviderEnabled(String provider) | |
| { | |
| } | |
| @Override public void onStatusChanged(String provider, int status, Bundle extras) | |
| { | |
| } | |
| /** | |
| * @brief The location response for the callback of the LocationHelper | |
| */ | |
| public static abstract class LocationResponse | |
| { | |
| /** | |
| * Called when the request was initiated | |
| */ | |
| public void onRequest() | |
| { | |
| } | |
| /** | |
| * Called when the location changes | |
| * | |
| * @param l | |
| * The new location | |
| */ | |
| public void onLocationChanged(Location l) | |
| { | |
| } | |
| /** | |
| * Called when the location was aquired | |
| * | |
| * @param l | |
| * The location recieved | |
| */ | |
| public abstract void onLocationAquired(Location l); | |
| /** | |
| * Called when the request timed out | |
| */ | |
| public void onTimeout() | |
| { | |
| } | |
| /** | |
| * Called when the request failed | |
| * | |
| * @param message | |
| * The message | |
| * @param messageId | |
| * The ID of the message | |
| */ | |
| public void onLocationFailed(String message, int messageId) | |
| { | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment