I am writing an app that requires the user\'s current location (lastknownlocation won\'t be very helpful) and displays a list of all the closest \"items\" to them taken from
Instead of creating an AsyncTask why didn't you create a ProgressDialog box and dismiss it on public void gotLocation(final Location location){}
? You can also add a onCancelListener to the ProgressDialog box and cancel any current location requests.
I still don't like how this works at all and it seems way more complicated than it should be but until someone provides a better way I have it working for now...
If someone comes across this and suggest a much better cleaner result to just get the user's current location coordinates just once then stop looking that would be greatly appreciated!!
private LocationControl locationControlTask;
private boolean hasLocation = false;
LocationHelper locHelper;
From onCreate() I call
locHelper = new LocationHelper();
locHelper.getLocation(context, locationResult);
locationControlTask = new LocationControl();
locationControlTask.execute(this);
I then have a a private class LocationControl
private class LocationControl extends AsyncTask<Context, Void, Void>
{
private final ProgressDialog dialog = new ProgressDialog(activityname.this);
protected void onPreExecute()
{
this.dialog.setMessage("Searching");
this.dialog.show();
}
protected Void doInBackground(Context... params)
{
//Wait 10 seconds to see if we can get a location from either network or GPS, otherwise stop
Long t = Calendar.getInstance().getTimeInMillis();
while (!hasLocation && Calendar.getInstance().getTimeInMillis() - t < 15000) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
return null;
}
protected void onPostExecute(final Void unused)
{
if(this.dialog.isShowing())
{
this.dialog.dismiss();
}
if (currentLocation != null)
{
useLocation();
}
else
{
//Couldn't find location, do something like show an alert dialog
}
}
}
Then a locationResult..
public LocationResult locationResult = new LocationResult()
{
@Override
public void gotLocation(final Location location)
{
currentLocation = new Location(location);
hasLocation = true;
}
};
Also to avoid you pulling your hair out like I did for ages remember to stop the locationcontrol task if someone leaves the activity early and also stop location updates to stop the GPS from running when the user leaves. In onStop() do something like this:
locHelper.stopLocationUpdates();
locationControlTask.cancel(true);
Also stopLocationUpdates in the Location Helper class does the following:
public void stopLocationUpdates()
{
locationManager.removeUpdates(locationListenerGps);
locationManager.removeUpdates(locationListenerNetwork);
}
Good luck with it, I needed it...
Use an AsyncTask and use both network_provider as well as gps_provider, which means two listeners. gps takes longer to get a fix, maybe sometimes a minute and only works outdoors, while network gets a location pretty fast.
A good code example is here: What is the simplest and most robust way to get the user's current location on Android?
For AsyncTask, look http://developer.android.com/reference/android/os/AsyncTask.html
There are also many code example here on SO for it, for example here: Android Show a dialog until a thread is done and then continue with the program
EDIT: code concept:
add class variable
boolean hasLocation = false;
call in onCreate (not in AsyncTask):
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
then in locationListener.onLocationChanged, change the value once a location is found:
boolean hasLocation = false;
AsyncTask: leave as it is, but don't call
LocationHelper location = new LocationHelper();
location.getLocation(params[0], locationResult);
there, instead do
Long t = Calendar.getInstance().getTimeInMillies();
while (!hasLocation && Calendar.getInstance().getTimeInMillies()-t<30000)) {
Thread.Sleep(1000);
};
probably with a delay in between would be sufficient.