package com.electronapps.LJPro; import java.io.IOException; import java.util.List; import android.content.Context; import android.location.Address; import android.location.Criteria; import android.location.Geocoder; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationProvider; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; public class GetLocation { private Context mContext; private Location mBestLocation; private CoordsCallBack mCoordsCallBack; private LocationCallBack mLocCallBack; private LocationProvider mLow; private LocationManager mLocMgr; public interface LocationCallBack { public void onHaveAddress(String location); } public interface CoordsCallBack { public void onNewLocation(Location location); } public GetLocation(Context c,CoordsCallBack coords, LocationCallBack callback){ mContext=c; mGeocoder=new Geocoder(mContext); mCoordsCallBack=coords; mLocCallBack=callback; } /** this criteria will settle for less accuracy, high power, and cost */ public static Criteria createCoarseCriteria() { Criteria c = new Criteria(); c.setAccuracy(Criteria.ACCURACY_COARSE); c.setAltitudeRequired(false); c.setBearingRequired(false); c.setSpeedRequired(false); c.setCostAllowed(true); c.setPowerRequirement(Criteria.POWER_HIGH); return c; } /** this criteria needs high accuracy, high power, and cost */ public static Criteria createFineCriteria() { Criteria c = new Criteria(); c.setAccuracy(Criteria.ACCURACY_FINE); c.setAltitudeRequired(false); c.setBearingRequired(false); c.setSpeedRequired(false); c.setCostAllowed(true); c.setPowerRequirement(Criteria.POWER_HIGH); return c; } /** make sure to call this in the main thread, not a background thread make sure to call locMgr.removeUpdates(...) when you are done */ public void init(){ mLocMgr =(LocationManager) mContext.getApplicationContext().getSystemService(Context.LOCATION_SERVICE); Location location = null; List<String> providers = mLocMgr.getAllProviders(); for (int i = 0; i < providers.size(); ++i) { String provider = providers.get(i); location = (provider != null) ? mLocMgr.getLastKnownLocation(provider) : null; if (location != null) break; } mBestLocation = location; if (location!=null) { mCoordsCallBack.onNewLocation(location); makeUseOfNewLocation(location); } // get low accuracy provider mLow=mLocMgr.getProvider(mLocMgr.getBestProvider(createCoarseCriteria(), false)); // get high accuracy provider LocationProvider mHigh=mLocMgr.getProvider(mLocMgr.getBestProvider(createFineCriteria(), false)); // using low accuracy provider... to listen for updates mLocMgr.requestLocationUpdates(mLow.getName(), 5000, 0f,mListener); // using high accuracy provider... to listen for updates mLocMgr.requestLocationUpdates(mHigh.getName(), 5000, 0f,mListener); } static float ACCURACY_THRESHOLD=10f; LocationListener mListener=new LocationListener() { public void onLocationChanged(Location location) { makeUseOfNewLocation(location); // we have a good enough fix so let's stop if (location.getAccuracy()<ACCURACY_THRESHOLD); cancel(); } public void onStatusChanged(String s, int i, Bundle bundle) { } public void onProviderEnabled(String s) { // try switching to a different provider } public void onProviderDisabled(String s) { // try switching to a different provider } }; Geocoder mGeocoder; private void makeUseOfNewLocation(Location location) { if (isBetterLocation(location)){ mBestLocation=location; float[] latlong={(float) mBestLocation.getLatitude(),(float) mBestLocation.getLongitude()}; ReverseGeocoderTask lookupAddress=new ReverseGeocoderTask(mGeocoder, latlong, mLocCallBack); lookupAddress.execute(); } } private static final int TWO_MINUTES = 1000 * 60 * 2; /** Determines whether one Location reading is better than the current Location fix * @param location The new Location that you want to evaluate * @param currentBestLocation The current Location fix, to which you want to compare the new one */ protected boolean isBetterLocation(Location location) { final Location currentBestLocation=mBestLocation; 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 > TWO_MINUTES; boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; 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); } public class ReverseGeocoderTask extends AsyncTask<Void, Void, String> { private static final String TAG = "ReverseGeocoder"; private Geocoder mGeocoder; private float mLat; private float mLng; private LocationCallBack mCallback; public ReverseGeocoderTask(Geocoder geocoder,float[] latlng, LocationCallBack callback) { mGeocoder = geocoder; mLat = latlng[0]; mLng = latlng[1]; mCallback = callback; } @Override protected String doInBackground(Void... params) { String value =""; try { List<Address> address = mGeocoder.getFromLocation(mLat, mLng, 1); StringBuilder sb = new StringBuilder(); Address addr=address.get(0); if(addr.getLocality()!=null) sb.append(addr.getLocality()); if(addr.getAdminArea()!=null) sb.append(","+addr.getAdminArea()); if(addr.getCountryCode()!=null) sb.append(","+addr.getCountryCode()); value = sb.toString(); } catch (IOException ex) { value = ""; Log.e(TAG, "Geocoder exception: ", ex); } catch (RuntimeException ex) { value = ""; Log.e(TAG, "Geocoder exception: ", ex); } return value; } @Override protected void onPostExecute(String location) { mCallback.onHaveAddress(location); } } public void cancel() { mLocMgr.removeUpdates(mListener); } }