java.time and ThreeTenABP
To obtain your time in millseconds since the epoch for the triggerAtMillis
argument for your alarm manager:
long triggerAtMillis = ZonedDateTime.now(ZoneId.systemDefault())
.with(LocalTime.of(11, 55))
.toInstant()
.toEpochMilli();
To have this code work also on Android versions before Oreo (version code O, API level 26), add ThreeTenABP to your Android project, see the link at the bottom. And then make sure you import org.threeten.bp.ZonedDateTime
, org.threeten.bp.ZoneId
and org.threeten.bp.LocalTime
.
What went wrong in your code?
The Calendar
class was always poorly designed and has a confusing interface. No wonder that you made this error. You’re far from the first and unfortunately not the last either. In the original question you tried:
calendar.set(Calendar.WEEK_OF_YEAR, Calendar.MONTH , Calendar.DAY_OF_MONTH, 11, 55, 0);
In my time zone this sets the calendar date to Mon Mar 05 11:55:00 CET 3
. That’s 2016 years and some months ago. So the alarm manager did the correct thing when running as soon as your app was opened. Could it be that you passed year 3, month 3 and day of month 5 to the method? Almost! The Calendar
interface is working with fields that can be set independently: an era field, a year field, a month field, etc. Since this was designed before enums in Java, each field has a number, and of course a named constant for that number. The month field, for example, is field 2, so when you pass Calendar.MONTH
for month, you are passing the value 2. So how come we get March? This is another confusing trait of Calendar
, months are numbered from 0 for January through 11 for December, so 2 means March. The week of year field is field 3 and the day of month field is field 5. This explains the date you got.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
- In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
- In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
- On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from
org.threeten.bp
with subpackages.
Links