Android - Controlling a task with Timer and TimerTask?

Donal Rafferty picture Donal Rafferty · Jan 29, 2010 · Viewed 76.3k times · Source

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?

Answer

CommonsWare picture CommonsWare · Jan 29, 2010

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);
        }
    }
};