Reputation: 1
i m using lat/lng to find where is my user and calculate the distance between him and another place in the map(its lat/lng is static).In order to do this i use :
private void findloc() {
// TODO Auto-generated method stub
try{
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
Double lat = Double.valueOf(location.getLatitude());
Double lng = Double.valueOf(location.getLongitude());
Location location2 = new Location("gps");
location2.setLatitude(35.519583);
location2.setLongitude(24.016864);
float distance = location2.distanceTo(location);
TextView sitesdistancekm = (TextView) findViewById(R.id.sitesdistancekm);
sitesdistancekm.setText("Geographical Distance : "+distance/1000+" km");
Toast.makeText(otto.this, "lat: "+lat+"\nlng: "+lng,
Toast.LENGTH_LONG).show();
}
catch(Exception e){
TextView sitesdistancekm = (TextView) findViewById(R.id.sitesdistancekm);
sitesdistancekm.setText("No GPS signal");
}
}
My problem is that sometimes the location stacks and i m getting a wrong distance .i m calling findloc() as a refresh for the menu but it doesnt changes.
public boolean onOptionsItemSelected(MenuItem item) {
findloc();
return true;
}
Is there any way to improve it?Any idea please??
EDIT
Is that gonna work?
private void findloc() {
// TODO Auto-generated method stub
try{
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
Double lat = Double.valueOf(location.getLatitude());
Double lng = Double.valueOf(location.getLongitude());
location2 = new Location("gps");
location2.setLatitude(35.519583);
location2.setLongitude(24.016864);
float distance = location2.distanceTo(location);
TextView sitesdistancekm = (TextView) findViewById(R.id.sitesdistancekm);
sitesdistancekm.setText("Geographical Distance : "+distance/1000+" km");
Toast.makeText(otto.this, "lat: "+lat+"\nlng: "+lng,
Toast.LENGTH_LONG).show();
onLocationChanged(location);
}
catch(Exception e){
TextView sitesdistancekm = (TextView) findViewById(R.id.sitesdistancekm);
sitesdistancekm.setText("No GPS signal");
}
}
private void onLocationChanged(Location location) {
// TODO Auto-generated method st
float distance = location2.distanceTo(location);
TextView sitesdistancekm = (TextView) findViewById(R.id.sitesdistancekm);
sitesdistancekm.setText("Geographical Distance : "+distance/1000+" km");
}
Upvotes: 0
Views: 577
Reputation: 21353
Referring to answer by Jack, getLastKnownLocation should not be used as sole measure of location detection. You need to divide your location detection logic to several steps:
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
// you need to specify the criteria here
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String bestProvider = lm.getBestProvider(criteria, true);
Location locate = lm.getLastKnownLocation(bestProvider);
if(System.currentTimeMillis() - locate.getTime() < TIME_TO_EXPIRE) {
// this is a valid location, let's use this location
// as the last time the provider check is within reasonable boundary
}
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,
MIN_TIME, MIN_DISTANCE, locationListener);
As you can see, you don't call onLocationChange manually, but rather let the provider calls the listener if MIN_TIME and MIN_DISTANCE have been exceeded.
Note that if your position hasn't changed then onLocationChanged() will not get called. If certain period has passed without onLocationChanged getting called, you can assume your last known position is the most accurate one and you should use it.
There is also chance that the onLocationChanged() doesn't get called because the provider can't get a fix for your position. In this case, optionally, you could call other provide to see if they could provide you with location update before relying back on last known position
Upvotes: 1
Reputation: 9252
I've found that getLastKnownLocation() is not as reliable as registering a location listener. See this post for good information on how to implement one.
getLastKnownLocation docs state:
Returns a Location indicating the data from the last known location fix obtained from the given provider. This can be done without starting the provider. Note that this location could be out-of-date, for example if the device was turned off and moved to another location.
For me, I use getLastKnownLocation() to get an initial location, but then register a listener for anything else.
Upvotes: 2