Edit: I'm rewriting this question because I apparently wasn't clear.
Sometimes the GPS service on Android phones takes a long time to get a fix. Sometimes it's fast, sometimes it takes hours. I know and accept this.
I have an application that does many things. One of the things it must do is allow the user to click a button to send their current coordinates to a server. What I need are the coordinates of the phone when the user clicks the button or within a reasonably short time thereafter.
Because I know that getting a GPS fix is not instant and I know that it could take minutes or hours (during which the user has moved a great distance), I need to code a timeout for this feature. For this feature, it is simply not acceptable to upload the GPS location of the user three minutes (for example) after they clicked the button. It's fine if it takes 45 seconds, not okay if it takes 75 seconds. It's fine to give the user an error notification if the feature failed to get a location fast enough.
I need a feature to 'get the GPS location and send it to the server, unless it takes more than one minute'.
My original code is below. I have changed some things since posting it. I have added a Timer in the onStartCommand() method. I start a TimerTask that after 60 seconds will call my stop() method. At the beginning of the onLocationChanged() method, I cancel the TimerTask.
My question is: Is the Timer scheme a good way of implementing this timeout? Is there a better way?
Original question:
I'm writing an Android application that, among other things, needs to send the current GPS coordinates to a server when the user tells it to. From a context menu, I run the service below. The service is a LocationListener and requests updates from the LocationManager. When it gets a location (onLocationChanged()), it removes itself as a listener and sends the coordinates off to the server. All of this is working.
However, if GPS coordinates are not quickly available, my service just keeps running until it gets some. It holds up the UI with a progress dialog, which is annoying. Worse, if the user has moved since starting the service, the first GPS coordinates might be wrong and the app will send bad data to the server.
I need a timeout on the service. Is there a good way to do that? I'm not very experienced with threads. I think I can run a Runnable in the onStartCommand() method that will somehow count down 30 seconds and then, if there is no GPS result yet, call my service's stop() method. Does that sound like the best way to do this?
Alternatively, is it possible to tell if the GPS cannot get a fix? How would I go about doing that?
Edit: To further clarify, I'm looking for the best way to "give up" on getting a Location after some amount of time.
public class AddCurrentLocation extends Service implements LocationListener {
Application app;
LocationManager mLocManager;
ProgressDialog mDialog;
@Override
public int onStartCommand(Intent intent, int arg0, int arg1) {
app = getApplication();
// show progress dialog
if (app.getScreen() != null) {
mDialog = ProgressDialog.show(app.getScreen(), "", "Adding Location. Please wait...", true);
}
// find GPS service and start listening
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
mLocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
String bestProvider = mLocManager.getBestProvider(criteria, true);
mLocManager.requestLocationUpdates(bestProvider, 2000, 0, this);
return START_NOT_STICKY;
}
private void stop() {
mLocManager.removeUpdates(this);
if (mDialog != null) {
mDialog.dismiss();
}
stopSelf();
}
@Override
public void onLocationChanged(Location location) {
// done with GPS stop listening
mLocManager.removeUpdates(this);
sendLocation(location); // method to send info to server
stop();
}
// other required methods and sendLocation() ...
}