date and time not working in Alarm Manager

假装没事ソ 提交于 2019-12-14 03:22:41

问题


I'm having trouble working with the AlarmManager. I want to run AlarmManager using Calendar at a specific time. But the calendar doesn't work and AlarmManager always runs regardless of the time taken from the calendar.

 AlarmManager mAlarmManger = (AlarmManager) Objects.requireNonNull(activity).getSystemService(view.getContext().ALARM_SERVICE);
 Intent intent = new Intent(activity, MyReceiver.class);
 PendingIntent pendingIntent = PendingIntent.getBroadcast(activity, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

 Calendar calendar = Calendar.getInstance();
 calendar.set(Calendar.WEEK_OF_YEAR, Calendar.MONTH , Calendar.DAY_OF_MONTH, 11, 55, 0);
 calendar.set(Calendar.AM_PM, Calendar.AM);

 if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){

        mAlarmManger.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
    }
    else{

        mAlarmManger.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
    }

AlarmManager should run at 11:55 AM everyDay, but will run as soon as the app opens.


回答1:


  Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 11);
        calendar.set(Calendar.MINUTE, 30);
        calendar.set(Calendar.SECOND, 0);     

if (calendar.getTimeInMillis() > System.currentTimeMillis()) {

            Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
            pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
            am.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24 * 60 * 60 * 1000, pendingIntent); //Repeat every 24 h
}

Try this..




回答2:


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

  • Oracle tutorial: Date Time explaining how to use java.time.
  • Java Specification Request (JSR) 310, where java.time was first described.
  • ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
  • ThreeTenABP, Android edition of ThreeTen Backport
  • Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.


来源:https://stackoverflow.com/questions/57743785/date-and-time-not-working-in-alarm-manager

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!