Reputation: 914
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
Upvotes: 9
Views: 10591
Reputation: 187
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
Upvotes: 0
Reputation: 914
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
Upvotes: 4
Reputation: 9726
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);
}
Upvotes: 8