Android - Controlling a task with Timer and TimerTask?

I am currently trying to set up a WiFi Scan in my Android application that scans for WiFi access points every 30 seconds.

I have used Timer and TimerTask to get the scan running correctly at the intervals which I require.

However I want to be able to stop and start the scanning when the user presses a button and I am currently having trouble stopping and then restarting the Timer and TimerTask.

Here is my code

TimerTask scanTask;
final Handler handler = new Handler();
Timer t = new Timer();

public void doWifiScan(){

scanTask = new TimerTask() {
        public void run() {
                handler.post(new Runnable() {
                        public void run() {
                         wifiManager.scan(context); 
                         Log.d("TIMER", "Timer set off");
                        }
               });
        }};


    t.schedule(scanTask, 300, 30000); 

 }

  public void stopScan(){

   if(scanTask!=null){
      Log.d("TIMER", "timer canceled");
      scanTask.cancel();
 }

}

So the Timer and Task start fine and the scan happens every 30 seconds however I cant get it to stop, I can stop the Timer but the task still occurs and scanTask.cancel() doesn't seem to work either.

Is there a better way to do this? Or am I missing something in the Timer/TimerTask classes?


You might consider:

  • Examining the boolean result from calling cancel() on your task, as it should indicate if your request succeeds or fails
  • Try purge() or cancel() on the Timer instead of the TimerTask

If you do not necessarily need Timer and TimerTask, you can always use postDelayed() (available on Handler and on any View). This will schedule a Runnable to be executed on the UI thread after a delay. To have it recur, simply have it schedule itself again after doing your periodic bit of work. You can then monitor a boolean flag to indicate when this process should end. For example:

private Runnable onEverySecond=new Runnable() {
    public void run() {
        // do real work here

        if (!isPaused) {
            someLikelyWidget.postDelayed(onEverySecond, 1000);
        }
    }
};

using your code, instead of

scanTask.cancel();

the correct way is to cancel your timer (not timerTask):

t.cancel();

The Android documentation says that cancel() Cancels the Timer and all scheduled tasks. If there is a currently running task it is not affected. No more tasks may be scheduled on this Timer. Subsequent calls do nothing. Which explains the issue.