I want to show a dialog while the location of the device is determined. I also want to use both the wifi and gps provider. When the location changes, the latitude and longitude values should be updated. I looked for an example but I didn't find anything.
Asked
Active
Viewed 1,688 times
0
-
Take a look on this example: [How do I get the current GPS location programmatically in Android][1] [1]: http://stackoverflow.com/questions/1513485/how-do-i-get-the-current-gps-location-programmatically-in-android/12963889#12963889 – Maxim Shoustin Oct 23 '12 at 12:28
-
Check out some [tutorials](http://www.vogella.com/articles/AndroidLocationAPI/article.html). Then Toast `onLocationChanged()` or something – jnthnjns Oct 23 '12 at 12:28
-
read this http://www.vogella.com/articles/AndroidLocationAPI/article.html – koti Oct 23 '12 at 12:28
-
you can not use both GPS & WiFi at same time. – Lucifer Oct 23 '12 at 12:36
-
apparently you don't know about this site: developer.android.com is all in there. – Budius Oct 23 '12 at 12:39
1 Answers
1
Here is an example how to define location Manager and get on location change event:
public class LocationChangeListener implements LocationListener{
private LocationManager mLocationManager = null;
private static final int TWO_MINUTES = 1000 * 60 * 2;
private Location currentBestLocation = null;
public LocationChangeListener(Context context) {
super(context);
}
public void impl(int refreshPeriod, int accuracyInMeters){
// Get the location manager
mLocationManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
currentBestLocation = getLastBestLocation();
boolean enabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// Check if enabled and if not send user to the GSP settings
// Better solution would be to display a dialog and suggesting to
// go to the settings
if (!enabled) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
Criteria criteria = new Criteria();
//criteria.setAccuracy(Criteria.ACCURACY_FINE);
//criteria.setCostAllowed(false);
String provider = mLocationManager.getBestProvider(criteria, false);
Location location = mLocationManager.getLastKnownLocation(provider);
LocationListener listener = this;
mLocationManager.requestLocationUpdates(provider, refreshPeriod, accuracyInMeters, listener);
//mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
//mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener);
this.onLocationChanged(location);
// Initialize the location fields
if (location == null) {
//Location not available
mLocationManager.removeUpdates(this);
}
}
/**
* This method returns the last know location, between the GPS and the Network one.
* For this method newer is best :)
*
* @return the last know best location
*/
private Location getLastBestLocation() {
Location locationGPS = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location locationNet = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
long GPSLocationTime = 0;
if (null != locationGPS) { GPSLocationTime = locationGPS.getTime(); }
long NetLocationTime = 0;
if (null != locationNet) {
NetLocationTime = locationNet.getTime();
}
if ( 0 < GPSLocationTime - NetLocationTime ) {
return locationGPS;
}
else{
return locationNet;
}
}
/**
* This method modify the last know good location according to the arguments.
*
* @param location the possible new location
*/
void makeUseOfNewLocation(Location location) {
if ( isBetterLocation(location, currentBestLocation) ) {
currentBestLocation = location;
}
}
public void onLocationChanged(Location location) {
makeUseOfNewLocation(location);
if(currentBestLocation == null){
currentBestLocation = location;
}
FlowController.isTriggerEventReceived = true;
mCobytLocationCallback.onLocationChanged(currentBestLocation);
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
/** 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, 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 > 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 void destroyManager() {
if(mLocationManager != null){
mLocationManager.removeUpdates(this);
mLocationManager = null;
}
}
}
Since Android has
GPS_PROVIDER and NETWORK_PROVIDER
you can register to both and start fetch events from onLocationChanged(Location location) from 2 at the same time. So far so good. Now the question do we need 2 results or we should take the best. As I know NETWORK PROVIDER results have better accuracy than GPS.
Before we start listen on Location change we will implement followed method private Location getLastBestLocation(). This method returns the last know location, between the GPS and the Network one. For this method newer is best.
Maxim Shoustin
- 78,004
- 28
- 199
- 222
-
why you are adding importing statements, they are of no use in code-display, it only increases user readability. Remove it and make your answer more good readable form :) – Lucifer Oct 23 '12 at 12:47
-
You are right, sometimes I get questions about witch package I use, for Location in current example its not relevant. Thanks – Maxim Shoustin Oct 23 '12 at 14:07
-
FYI, GPS is better when outdoors but not when inside. Wifi generally gets an accuracy of 10 meters at best, where as GPS can do better when outside but terribly worst when indoors. – Joshua Pinter Aug 16 '14 at 18:44
-
Also, you should try using Google Play Services now, which was released in 2013. It fuses the various methods together into a simple API for getting the best available location: https://developer.android.com/google/play-services/index.html – Joshua Pinter Aug 16 '14 at 18:45