I would like to start a task at a specific time. For that I use runnable
and postDelayed
method as follows:
private Runnable mLaunchTask = new Runnable() {
public void run() {
try {
MY TASK
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
In my code I use mLunchTask
as follows:
mHandler = new Handler();
mHandler.postDelayed(mLaunchTask, myDelay*1000);
and myDelay
is computed as follows:
s = DateFormat.format("hh:mm:ss aaa", d.getTime());
cTime = s.toString(); // current Time
ch = Integer.parseInt(cTime.substring(0,2)); // current hour
cm = Integer.parseInt(cTime.substring(3,5)); // current minute
cs = Integer.parseInt(cTime.substring(6,8)); // current second
if (cTime.substring(9,11).equalsIgnoreCase("pm") && (ch<12) ) ch = ch+12;
myDelay=(desiredHour-ch)*3600+(desiredMinute-cm)*60 - cs;
if (myDelay<0) myDelay = 0;
and desiredHour
and desiredMinute
are set by user. The expectation is that MY TASK
starts at desiredHour
and desiredMinute
and 0 seconds.
However "MY TASK starts with a few seconds delay, which looks like is random.
Based on the above code, is there any reason that it does not start at the exact desired time?
Thanks
First of all, your delay calculation is correct, but the "pm" detection doesn't work with other languages. It is much better to use the calendar to get the delay:
Calendar calendar = Calendar.getInstance();
long currentTimestamp = calendar.getTimeInMillis();
calendar.set(Calendar.HOUR_OF_DAY, desiredHour);
calendar.set(Calendar.MINUTE, desiredMinute);
calendar.set(Calendar.SECOND, 0);
long diffTimestamp = calendar.getTimeInMillis() - currentTimestamp;
long myDelay = (diffTimestamp < 0 ? 0 : diffTimestamp);
Now you have the delay in milli secs and can start the handler:
new Handler().postDelayed(mLaunchTask, myDelay);
In my test the following runnable logs at the desired time with no delay.
private Runnable mLaunchTask = new Runnable() {
public void run() {
Calendar calendar = Calendar.getInstance();
Log.d("test", "started at "
+ calendar.get(Calendar.HOUR_OF_DAY) + " "
+ calendar.get(Calendar.MINUTE) + " "
+ calendar.get(Calendar.SECOND)
);
}
};
Maybe your started task needs some seconds to be loaded?
Could the AlarmManager be an alternative?