calender.add 在 android 中运作不佳

calender.add not functioning well in android

我编写此代码的目的是确保我的应用程序会在特定时间通知用户,并且这些应用程序将从每天早上 7 点开始重复相同的通知。

不过,我尝试使用这个功能(如下图)。但是好像不行。

calender.add(DATE, 1)

实际上,我想生成一个自动通知。服药信息和每日重复次数由用户输入。

So the things that I want to do is for the if statement, it would compare whether the current hour is between 7 AM - 8 PM.

For the else if, the statement is to compare either the current hour is after 8 PM or not, if yes then the calendar will add another 1 day. So that the apps will pop up the same notification the next day at 7 AM.

And for else statement is to check if the current hour is before 7 AM or not. If yes, apps will pop up the notification right after the current hour equals to 7 AM

但是 else if 语句没有像我预期的那样工作。我的意思是,如果我现在设置通知,即晚上 10 点,应用程序将不会在第二天(早上 7 点)通知我。

所以,我想问问你们是否有人可以帮助我修复我的代码,如下所示。 if 和 else 部分工作正常。但是 else if 语句似乎不起作用。

 AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

Calendar calendar = Calendar.getInstance();
Calendar now = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());

//repeat on 7am
calendar.set(Calendar.HOUR_OF_DAY, 7);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 0);

//check current hour
int timeOfDay = now.get(Calendar.HOUR_OF_DAY);

//to check if current hour is after 7pm
Calendar later = Calendar.getInstance();
later.set(Calendar.HOUR_OF_DAY, 20);
later.set(Calendar.MINUTE, 00);
later.set(Calendar.SECOND, 0);

if (timeOfDay >= 7 && timeOfDay <= 20) {
    //notification's process
}

else if (now.after(later)) {
        Log.d("Hey", "Added a day");
        calendar.add(Calendar.DATE, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 7);
        calendar.set(Calendar.MINUTE, 00);
        calendar.set(Calendar.SECOND, 0);

        this.context = context;
        prefs = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
        nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notification = new NotificationCompat.Builder(context);
        name = prefs.getString("name" + count, "");
        hours = prefs.getInt("hora" + count, 8);
        minutes = prefs.getInt("minuto" + count, 0);


        Intent newIntentKill = new Intent(context, Broadcast.class);
        Bundle saco = new Bundle();
        saco.putInt("count", count);
        saco.putBoolean("shownBefore", true);
        newIntentKill.putExtras(saco);

        PendingIntent pendingIntentKill = PendingIntent.getBroadcast(context, count, newIntentKill, PendingIntent.FLAG_UPDATE_CURRENT);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
               alarmManager.setExact(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntentKill);

         } else {
               alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntentKill);
         }

            Log.d("Alarm", "Alarms set for everyday 7 am.");
    }

else {

    this.context = context;
    prefs = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
    nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    notification = new NotificationCompat.Builder(context);
    name = prefs.getString("name" + count, "");
    hours = prefs.getInt("hora" + count, 8);
    minutes = prefs.getInt("minuto" + count, 0);


    Intent newIntentKill = new Intent(context, Broadcast.class);
    Bundle saco = new Bundle();
    saco.putInt("count", count);
    saco.putBoolean("shownBefore", true);
    newIntentKill.putExtras(saco);

    PendingIntent pendingIntentKill = PendingIntent.getBroadcast(context, count, newIntentKill, PendingIntent.FLAG_UPDATE_CURRENT);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
           alarmManager.setExact(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntentKill);

     } 
     else {
           alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntentKill);
         }

     Log.d("Alarm", "Alarms set for everyday 7 am.");
}

所以,在此先感谢您的帮助。我真的很感激。

java.time 和 ThreeTenABP

我建议使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。与旧的和设计不佳的 Calendar class 相比,它更好用,而且通常不会带来那么多不愉快的惊喜。例如,您的 if/else 方案可以是这样的:

    ZoneId zone = ZoneId.systemDefault();
    ZonedDateTime nowZdt = ZonedDateTime.now(zone);
    LocalTime now = nowZdt.toLocalTime();
    if (now.isBefore(LocalTime.of(20, 0))) {
        if (now.isBefore(LocalTime.of(7, 0))) {
            // Set alarm for 7 today
            long alarmTimeMillis = nowZdt.with(LocalTime.of(7, 0))
                    .toInstant()
                    .toEpochMilli();
            // Set alarm
        } else { // between 7 AM and 8 PM
            // notification's process
        }
    } else { // after 8 PM
        // Set alarm for 7 AM tomorrow
        long alarmTimeMillis = nowZdt.plusDays(1)
                .with(LocalTime.of(7, 0))
                .toInstant()
                .toEpochMilli();
        // Set alarm
    }           

编辑:在代码的两个地方 alarmTimeMillis 是自警报纪元以来的毫秒数。您可以在对 alarmManager.set()alarmManager.setExact().

的调用中使用它代替 calendar.getTimeInMillis()

你的代码出了什么问题?

我不确定发生了什么。我能够发现的可能问题是在这一行中:

if (timeOfDay >= 7 && timeOfDay <= 20) {

您只是在比较一天中的小时数,并且您正在使用 <=。这意味着当时间为 20:something,直到并包括 20:59 时,条件为真。所以在这种情况下,您不会进入要添加 1 天的分支。我不认为这是你想要的。

问题:java.time 不需要 Android API 26 级吗?

java.time 在新旧 Android 设备上都能很好地工作。它只需要至少 Java 6.

  • 在 Java 8 和更新的 Android 设备上(从 API 级别 26)内置了现代 API。
  • 在非Android Java 6 和 7 中获取 ThreeTen Backport,现代 classes 的 backport(ThreeTen 用于 JSR 310;请参阅底部的链接) .
  • 在(较旧的)Android 使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。并确保使用子包从 org.threeten.bp 导入日期和时间 classes。

链接