I have created a timer in activity, some times it works perfectly but some time it run faster than the specified execution period.Here is my code
public void StartTimer()
{try
{
// Start Timer
Log.e("", "time1 : " + AppConstants.TOTALTIME);
int millisUntilFinished = Integer.parseInt(AppConstants.TOTALTIME) * 60000;
final String hh = String.format("%02d",(int) ((millisUntilFinished / (1000 * 60 * 60)) % 24));
final String mm = String.format("%02d", (millisUntilFinished / 60000) % 60);
final String ss = (String.format("%02d",(millisUntilFinished % 60000 / 1000)));
Log.e("", "time : " + hh + ":" + mm + ":" + ss);
txtTime.setText(hh + ":" + mm + ":" + ss);
txtTimeSpent.setText("00:00:00");
t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (txtTimeSpent.getText().toString().trim().equalsIgnoreCase(hh + ":" + mm + ":" + ss))
{
if (t != null)
t.cancel();
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss a");
String enddate = sdf.format(c.getTime());
AppConstants.ENDTIME = enddate;
Intent intent = new Intent(act,TestSubmissionActivity.class);
startActivity(intent);
finish();
}
else
{
txtTimeSpent.setText(" "
+ String.format("%02d", hrSpent) + ":"
+ String.format("%02d", minSpent) + ":"
+ String.format("%02d", secSpent));
AppConstants.TIMETAKEN = txtTimeSpent.getText().toString().trim();
secSpent++;
if (secSpent == 60)
{
txtTimeSpent.setText(" "
+ String.format("%02d", hrSpent) + ":"
+ String.format("%02d", minSpent) + ":"
+ String.format("%02d", secSpent));
AppConstants.TIMETAKEN = txtTimeSpent.getText().toString().trim();
secSpent = 0;
minSpent++;
if (minSpent == 60)
{
txtTimeSpent.setText(" "
+ String.format("%02d", hrSpent)
+ ":"
+ String.format("%02d", minSpent)
+ ":"
+ String.format("%02d", secSpent));
AppConstants.TIMETAKEN = txtTimeSpent.getText().toString().trim();
minSpent = 0;
hrSpent++;
}
}
CountTimeSpend++;
if(CountTimeSpend==5)
{
CountTimeSpend=0;
try {
Date d=sdfDate.parse((sdfDate.format(c.getTime())+" "+txtTimeSpent.getText().toString().trim()));
new AsyncSaveTimeSpend().execute(d);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
}
});
}
}, 0, 1000);
}
catch(Exception e)
{
e.printStackTrace();
}
}
StartTimer() is get called inside a AsyncTask. and here is ondestroy()
@Override
protected void onDestroy() {
super.onDestroy();
if (t != null) {
t.cancel();
t.purge();
t = null;
}
}
Found solution to my problem. Don't know what was wrong in previous approach, but CountDownTimer
works perfectly. Here is my solution
public void StartTimer()
{
final long millisTotalTime = Integer.parseInt(AppConstants.TOTALTIME) * 60000;
hh = String.format("%02d",(int) ((millisTotalTime / (1000 * 60 * 60)) % 24));
mm = String.format("%02d", (millisTotalTime / 60000) % 60);
ss = (String.format("%02d",(millisTotalTime % 60000 / 1000)));
Log.e("", "time : " + hh + ":" + mm + ":" + ss);
txtTime.setText(hh + ":" + mm + ":" + ss);
txtTimeSpent.setText("00:00:00");
millisSpent=0;
countDownTimer=new CountDownTimer(millisTotalTime, 1000)
{
@Override
public void onTick(long millisUntilFinished)
{
millisSpent=millisTotalTime-millisUntilFinished;
hh = String.format("%02d",(int) ((millisSpent / (1000 * 60 * 60)) % 24));
mm = String.format("%02d", (millisSpent / 60000) % 60);
ss = (String.format("%02d",(millisSpent % 60000 / 1000)));
txtTimeSpent.setText( hh + ":"+ mm + ":"+ ss);
System.out.println("Time Spent=="+txtTimeSpent.getText());
AppConstants.TIMETAKEN = txtTimeSpent.getText().toString().trim();
CountTimeSpend++;
if(CountTimeSpend==5)
{
CountTimeSpend=0;
try {
Date d=sdfDate.parse((sdfDate.format(c.getTime())+" "+txtTimeSpent.getText().toString().trim()));
new AsyncSaveTimeSpend().execute(d);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
@Override
public void onFinish() {
Calendar c = Calendar.getInstance();
String enddate = sdf.format(c.getTime());
AppConstants.ENDTIME = enddate;
Intent intent = new Intent(act,TestSubmissionActivity.class);
act.startActivity(intent);
act.finish();
}
}.start();
}
And if you want to cancel the CountDownTimer
before its Specified time then just call countDownTimer.cancel();
Hope it helps some one :)