Question

I need my app to trigger an alert a specified amount of time after a user presses a button. The documentation makes it look like Handler is what I need, and usage appears to be brain dead.

However, I'm finding that despite using postDelayed, my routine is running immediately. I know I'm missing something obvious, but I just can't see it. Why does the code below make the phone vibrate the immediately rather than waiting a minute?

 ...

   final Button button = (Button) findViewById(R.id.btnRun);
   final Handler handler = new Handler();

   button.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {             
        ...
        handler.postDelayed(Vibrate(), 60000);

        }         
    });
...

    private Runnable Vibrate() {
    Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
    v.vibrate(300);
    return null;
   }
Was it helpful?

Solution

That's because you are doing it the wrong way. Just see the flow:

handler.postDelayed(Vibrate(), 60000) will call the Vibrate() method immediately, and then it runs the vibrator stuff. In fact Vibrate() returns null? What do you think that the handler will do with a null reference? You are lucky that it does not throw a NullPointerException. There are too many examples of how to correctly implement a handler... just dig a little bit more on google.

private class Vibrate implements Runnable{
  public void run(){
    Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
    v.vibrate(300);
  }
}

Then:

handler.postDelayed(new Vibrate(), 60000);

OTHER TIPS

You need to write a run() method for Vibrate:

private class Vibrate implements Runnable {
  public void run(){
    Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
    v.vibrate(300);
    //return null; don't return anything
  }
}

The simplest way for you would be to use anonymous object of Runnable,

...

final Button button = (Button) findViewById(R.id.btnRun); final Handler handler = new Handler();

Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

button.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            handler.postDelayed(new Runnable() {
                public void run() {
                    v.vibrate(300);
                }
            }, 60000);
        }
    });

...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top