Question

I am creating an app that vibrate and beep every 30 sec and when I log out the vibrate and beep must be cancelled and when I log in the vibrate and beep should resume.

NOTE: it must vibrate and beep for every 30 sec until I log out

In my app I am using TimerTask for this implementation

this is the code for vibrate and beep using TimerTask

static TimerTask Task;
final static Handler handler = new Handler();
static Timer t = new Timer();

public static void vib() {

    Task = new TimerTask() {
        public void run() {
            handler.post(new Runnable() {
                public void run() {
                    Vibrator vibrator = (Vibrator) ApplicationUtils.getContext().getSystemService(Context.VIBRATOR_SERVICE);
                    vibrator.vibrate(3000);
                    playSound();
                    Log.d("TIMER", "Timer set on");
                }
            });
        }
    };
    t.schedule(Task, 0, 30000); 
}

This is the code I'm using in logout section

public void stopvib() {
    if (Task != null) {
    //  Log.d("TIMER", "timer canceled");
        t.cancel();
        Task.cancel();
    }
}

Note: I also removed the Task.cancel(); but still I am getting same error

My vibrate working fine before logout and again login I am geting error

java.lang.IllegalStateException: Timer was cancelled
    at java.util.Timer.scheduleImpl(Timer.java:562)
    at java.util.Timer.schedule(Timer.java:481)
    at com.vib(AlertListActivity.java:724)

can any one help me with this coding. Where did I go wrong?

Was it helpful?

Solution

i have recently run this code and is working fine. This can be achieved using broadcast Receiver.You have to implement separate CustomTimer task that extend TimerTask:

Activity mActivity=null;
public MyCustomTimer(Activity mActivity) {
    this.mActivity=mActivity;
}
    @Override
    public void run() {
        this.mActivity.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                Toast.makeText(mActivity, "Write you code here",Toast.LENGTH_LONG).show();
                Log.d("MyCustomTimer","Call");
            }
        });

    }

After this you have to implement BroadCast Receive in that class where you want to implement " vib() " method.: Let say, in my case (just for example ) is MainActivity:

public class MainActivity extends Activity {
    private MyCustomTimer myCustomTimer = null;
    BroadcastReceiver mBr_Start = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("START_VIBRATION")) {
                System.out.println("onreceive :START_VIBRATION");
                vib();
            }
        }
    };
    BroadcastReceiver mBr_Stop = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("STOP_VIBRATION")) {
                stopVibration();
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        IntentFilter mIntentFilter = new IntentFilter();
        mIntentFilter.addAction("START_VIBRATION");
        registerReceiver(mBr_Start, mIntentFilter);
        IntentFilter mIntentFilter2 = new IntentFilter();
        mIntentFilter2.addAction("STOP_VIBRATION");
        registerReceiver(mBr_Stop, mIntentFilter2);

        Button b1 = (Button) findViewById(R.id.button1);
        b1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent i = new Intent(MainActivity.this, MySecondActivity.class)
                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);

            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    private void vib() {
        myCustomTimer = new MyCustomTimer(MainActivity.this);
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(myCustomTimer, 0, 30000);
    }

    private void stopVibration() {
        Log.d("MainActivity", "Before Cancel");
        if (null != myCustomTimer)
            myCustomTimer.cancel();
        Log.d("MainActivity", "After Cancel");
    }

}

Now,you can start Or stop vibration by implementing these lines: To start vibration:

Intent i=new Intent("START_VIBRATION");
                mActivity.sendBroadcast(i);

To Stop:

Intent i=new Intent("STOP_VIBRATION");
                mActivity.sendBroadcast(i);

Note: onDestroy() of MainActivity (in your case,Where you implement Broadcast Receiver,unregister BroadcastReceiver.)

OTHER TIPS

Set timer instance to null when you logout and then initialize it everytime user logged in the app. This will fix the "Timer was cancelled" related issues.

Why do you need a static TimerTask.You can give like this which works fine for me.

timer.schedule(new TimerTask() {
        @Override
        public void run() {
        //your code
        }
        }, 0, 30000);

While logout use, timer.cancel(). Here you can simply cancel the timer.No need to cancel the TimerTask.

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