日历在安卓上的”calender.add”功能运行不正常。

huangapple go评论83阅读模式
英文:

calender.add not functioning well in android

问题

以下是翻译好的内容:

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

然而,我尝试使用下面所示的函数(如下所示)。但似乎它不起作用。

calendar.add(DATE, 1)

实际上,我想要生成自动通知。药物信息和每日重复次数是用户输入。

所以我想要做的事情是,对于if语句,它将比较当前小时是否在上午7点到下午8点之间。

对于else if,语句是为了比较当前小时是否在晚上8点之后,如果是的话,日历将再添加1天。这样,应用程序将在第二天早上7点再次弹出相同的通知。

对于else语句,是为了检查当前小时是否在上午7点之前。如果是的话,应用程序将在当前小时等于上午7点后立即弹出通知。

但是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());

// 每天早上7点重复
calendar.set(Calendar.HOUR_OF_DAY, 7);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 0);

// 检查当前小时
int timeOfDay = now.get(Calendar.HOUR_OF_DAY);

// 检查当前小时是否在晚上8点之后
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) {
    // 通知的处理过程
} else if (now.after(later)) {
    Log.d("Hey", "添加了一天");
    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", "每天早上7点设置闹钟。");
} 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", "每天早上7点设置闹钟。");
}

非常感谢您提前的帮助,我会非常感激。

英文:

the purpose I'm writing this code is to make sure that my apps will notify the user on a certain time and the apps will be repeating the same notify every day starting at 7 AM.

However, I tried to use this function (as shown below). But it seems like it won't work.

> calender.add(DATE, 1)

Actually, I want to generate an automatic notification. The medication information and the number of daily repeated is user input.

> 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

But the else if statement didn't work as I expected. I mean if I set the notification right now, at 10 PM, the apps won't notify me on the next day (at 7 AM).

So, I would like to ask if any of you could help me to fix my code as shown below. The if and else segment just works fine. But the else if statement seems like won't work.

 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 &gt;= 7 &amp;&amp; timeOfDay &lt;= 20) {
//notification&#39;s process
}
else if (now.after(later)) {
Log.d(&quot;Hey&quot;, &quot;Added a day&quot;);
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(&quot;prefs&quot;, Context.MODE_PRIVATE);
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notification = new NotificationCompat.Builder(context);
name = prefs.getString(&quot;name&quot; + count, &quot;&quot;);
hours = prefs.getInt(&quot;hora&quot; + count, 8);
minutes = prefs.getInt(&quot;minuto&quot; + count, 0);
Intent newIntentKill = new Intent(context, Broadcast.class);
Bundle saco = new Bundle();
saco.putInt(&quot;count&quot;, count);
saco.putBoolean(&quot;shownBefore&quot;, true);
newIntentKill.putExtras(saco);
PendingIntent pendingIntentKill = PendingIntent.getBroadcast(context, count, newIntentKill, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntentKill);
} else {
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntentKill);
}
Log.d(&quot;Alarm&quot;, &quot;Alarms set for everyday 7 am.&quot;);
}
else {
this.context = context;
prefs = context.getSharedPreferences(&quot;prefs&quot;, Context.MODE_PRIVATE);
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notification = new NotificationCompat.Builder(context);
name = prefs.getString(&quot;name&quot; + count, &quot;&quot;);
hours = prefs.getInt(&quot;hora&quot; + count, 8);
minutes = prefs.getInt(&quot;minuto&quot; + count, 0);
Intent newIntentKill = new Intent(context, Broadcast.class);
Bundle saco = new Bundle();
saco.putInt(&quot;count&quot;, count);
saco.putBoolean(&quot;shownBefore&quot;, true);
newIntentKill.putExtras(saco);
PendingIntent pendingIntentKill = PendingIntent.getBroadcast(context, count, newIntentKill, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntentKill);
} 
else {
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntentKill);
}
Log.d(&quot;Alarm&quot;, &quot;Alarms set for everyday 7 am.&quot;);
}

So, thank you in advance for your help. I would really appreciate it.

答案1

得分: 0

java.time 和 ThreeTenABP

我建议在处理日期和时间时使用现代的 Java 日期和时间 API,即 java.time。与旧的且设计不佳的 Calendar 类相比,它更加易于使用,通常不会带来那么多令人不愉快的意外。例如,您的 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))) {
        // 设置今天早上 7 点的闹钟
        long alarmTimeMillis = nowZdt.with(LocalTime.of(7, 0))
                .toInstant()
                .toEpochMilli();
        // 设置闹钟
    } else { // 在早上 7 点到晚上 8 点之间
        // 通知的处理
    }
} else { // 晚上 8 点之后
    // 设置明天早上 7 点的闹钟
    long alarmTimeMillis = nowZdt.plusDays(1)
            .with(LocalTime.of(7, 0))
            .toInstant()
            .toEpochMilli();
    // 设置闹钟
}

注:在代码中的两个位置,alarmTimeMillis 是您的闹钟自纪元以来的毫秒数计数。您可以在调用 alarmManager.set()alarmManager.setExact() 时使用它代替 calendar.getTimeInMillis()

代码中出了什么问题?

我不确定发生了什么。我能够发现的可能问题在于这行代码:

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

您只比较了一天中的小时,而且使用了 <=。这意味着当时间为 20:xx,包括 20:59 在内时,条件是成立的。因此,在这种情况下,您没有进入您添加了一天的分支。我认为这不是您想要的结果。

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

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

  • 在 Java 8 及更高版本以及较新的 Android 设备(从 API 等级 26 开始),现代 API 已经内置。
  • 在非 Android 环境下,Java 6 和 7 需要使用 ThreeTen Backport,即现代类的后移版本(ThreeTen 用于 JSR 310;请参阅底部的链接)。
  • 在(较旧的)Android 上,请使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 和子包中导入日期和时间类。

链接

英文:

java.time and ThreeTenABP

I suggest using java.time, the modern Java date and time API, for your date and time work. It is so much nicer to work with than the old and poorly designed Calendar class and generally doesn’t give as many unpleasant surprises. Your if/else scheme could for instance go like this:

	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&#39;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
}			

Edit: In the two places in the code alarmTimeMillis is the count of milliseconds since the epoch for your alarm. You can use it in place of calendar.getTimeInMillis() in the calls to alarmManager.set() and alarmManager.setExact().

What went wrong in your code?

I’m not sure what happened. The possible problem that I have been able to spot is in this line:

if (timeOfDay &gt;= 7 &amp;&amp; timeOfDay &lt;= 20) {

You are only comparing the hour of day, and you are using &lt;=. This means that when the time is 20:something, up to and including 20:59, the condition is true. So in this case you are not getting into the branch where you are adding 1 day. I don’t think this is what you had intended.

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.

huangapple
  • 本文由 发表于 2020年4月5日 21:56:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/61043735.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定