Set a time-out for android requestSingleUpdate

AnjoMan picture AnjoMan · Feb 22, 2013 · Viewed 13.9k times · Source

I am using the routine requestSingleUpdate() reoutine of the android LocationManager library with a LocationListener. The functionality I am trying to implement is that the user can press a button and the app will get their current location and perform reverse geocoding to get the approximate address.

My problem is that depending on the network situation of the device, getting a location fix may take a long time. How can I implement a timeout that will cause my 'requestSingleUpdate()' to give up and tell the user to find out their own bloody address?

my code:

LocationManager locationManager = (LocationManager)  getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setPowerRequirement(Criteria.POWER_HIGH);

locationManager.requestSingleUpdate(criteria, new LocationListener(){

        @Override
        public void onLocationChanged(Location location) {
            // reverse geo-code location

        }

        @Override
        public void onProviderDisabled(String provider) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onProviderEnabled(String provider) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onStatusChanged(String provider, int status,
                Bundle extras) {
            // TODO Auto-generated method stub

        }

    }, null);

Answer

Dan Breslau picture Dan Breslau · Apr 9, 2013

LocationManager doesn't seem to have a timeout mechanism. But LocationManager does have a method named removeUpdates(LocationListener listener) which you can use to cancel any callbacks on the specified LocationListener.

So, you could implement your own timeout with something like the following pseudo-code:

    final LocationManager locationManager
        = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    // ...

    final LocationListener myListener = new LocationListener() {
         //... your LocationListener's methods, as above
    }

    Looper myLooper = Looper.myLooper();
    locationManager.requestSingleUpdate(criteria, myListener, myLooper);
    final Handler myHandler = new Handler(myLooper);
    myHandler.postDelayed(new Runnable() {
         public void run() {
             locationManager.removeUpdates(myListener);
         }
    }, MY_TIMEOUT_IN_MS);

I'm not certain what happens if you call locationManager.removeUpdates(myListener) after you get the Location. You might want to check for that before you call removeUpdates. Or, you could add something like this to the onLocationChanged method in your callback (and possibly to the other methods as well) :

    myHandler.removeCallbacks(myRunnable); // where myRunnable == the above Runnable