9

My app uses the LocationListener to get one position fix and then removeUpdates() once every minute (to conserve battery). The problem is that if a user moves inside then it will perpetually look for a signal, burning more battery. I was wondering if anyone knows of a public method within Location Manager I can use to removeUpdates if a signal isn't acquired within 15 seconds. I would then check for a position fix every five minutes until the user moves back outdoors. Does this make sense? Maybe there is a better method to timeout GPS signal acquisition? I have looked through the Location Manager public methods but I can't seem to find a way to do it. Thanks so much for your help! -Dom

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
GPSmaster
  • 844
  • 3
  • 15
  • 31

3 Answers3

8

Although GPSmaster's answer is accepted, I want to post the link to more elegant and simpler solution, I think - https://gist.github.com/777790/86b405debd6e3915bfcd8885c2ee11db2b96e3df. I have tried it myself and it worked =)

In case the link doesn't work, this is a custom LocationListener by amay077:

/**
 * Initialize instance.
 *
 * @param locaMan the base of LocationManager, can't set null.
 * @param timeOutMS timeout elapsed (mili seconds)
 * @param timeoutListener if timeout, call onTimeouted method of this.
 */
public TimeoutableLocationListener(LocationManager locaMan, long timeOutMS,
        final TimeoutLisener timeoutListener) {
    this.locaMan  = locaMan;
    timerTimeout.schedule(new TimerTask() {

        @Override
        public void run() {
            if (timeoutListener != null) {
                timeoutListener.onTimeouted(TimeoutableLocationListener.this);
            }
            stopLocationUpdateAndTimer();
        }
    }, timeOutMS);
}

/***
 * Location callback.
 *
 * If override on your concrete class, must call base.onLocation().
 */
@Override
public void onLocationChanged(Location location) {
    stopLocationUpdateAndTimer();
}

@Override
public void onProviderDisabled(String s) { }

@Override
public void onProviderEnabled(String s) { }

@Override
public void onStatusChanged(String s, int i, Bundle bundle) { }

private void stopLocationUpdateAndTimer() {
    locaMan.removeUpdates(this);

    timerTimeout.cancel();
    timerTimeout.purge();
    timerTimeout = null;
}

public interface TimeoutLisener {
    void onTimeouted(LocationListener sender);
}
lomza
  • 9,412
  • 15
  • 70
  • 85
  • any hint on how to use this, i have an activity that implements LocationListener ? but if i make it implements TimeoutableLocationListener i get an error "Interface expected here" ? – Hakim Jun 28 '16 at 05:54
4

So this is what I ended up doing.

This is what i added to the LocationListener note the global variables timertest and loccounter:

public class MyLocationListener implements LocationListener

{
    public void onStart() {
        if (timertest==false) {
            timertest=true;
            serviceHandler = new Handler();
            serviceHandler.postDelayed( new timer(),1000L );
        }
    }
    class timer implements Runnable {
          public void run() {
            ++loccounter;
            if (runtest==true && loccounter>8) {
                dt=200;
                runtest=false;
                stoplistening();
            } else serviceHandler.postDelayed( this, 1000L );
          }
    }
}

I start the timer right before requesting location updates.

public void locupdate(int minTime, float minDistance) {
    mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    mlocListener = new MyLocationListener();
    if (mlocListener != null && mlocManager != null) {
        mlocManager.removeUpdates(mlocListener);
    }
    loccounter=0;
    ((MyLocationListener) mlocListener).onStart();
    runtest=true;
    mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                minTime, minDistance, mlocListener);
}

and one last method within the location listener:

    public void stoplistening() {
        mlocManager.removeUpdates(mlocListener);
        loccounter=0;
    }

Hope this helps someone

icedman21
  • 1
  • 2
GPSmaster
  • 844
  • 3
  • 15
  • 31
0

Well my solution to this problem is somewhat very simple and I don't know if it's good practice. Let's assume we have a long named timeToQuit that determines how many millis you wanna wait before aborting the search for a position just put:

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 
                              2000, 0, locationListener);
Handler handler = new Handler();    // android.os.Handler
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        locationManager.removeUpdates(locationListener);
    }
};
handler.postDelayed(runnable, timeToQuit);

Of course you have to have a LocationListener and your own LocationListener. Values in locationManager.requestLocationUpdates are from my app so you propapbly should adapt them. This code works like a charm for me. I know I'm a little late, but I couldn't find this approach anywhere and propably it helps someone. Cheers

Max Belli
  • 167
  • 2
  • 7