java - calender.add 在 android 中无法正常运行
问题描述
我编写此代码的目的是确保我的应用程序将在特定时间通知用户,并且应用程序将从早上 7 点开始每天重复相同的通知。
但是,我尝试使用此功能(如下所示)。但它似乎不起作用。
日历。添加(日期,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());
//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 日期和时间 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))) {
// 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
中的两个地方是自警报纪元以来的毫秒数。您可以使用它来代替对和calendar.getTimeInMillis()
的调用。alarmManager.set()
alarmManager.setExact()
你的代码出了什么问题?
我不确定发生了什么。我能够发现的可能问题在这一行:
if (timeOfDay >= 7 && timeOfDay <= 20) {
您只是在比较一天中的时间,而您正在使用<=
. 这意味着当时间是 20:something 时,直到 20:59(包括 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,现代类的后向端口(ThreeTen 用于 JSR 310;请参阅底部的链接)。
- 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从
org.threeten.bp
子包中导入日期和时间类。
链接
- Oracle 教程:日期时间解释如何使用 java.time。
- Java 规范请求 (JSR) 310,
java.time
第一次描述的地方。 - ThreeTen Backport 项目,
java.time
Java 6 和 7 的反向移植(ThreeTen for JSR-310)。 - ThreeTenABP , ThreeTen Backport 的 Android 版
- 问题:如何在Android项目中使用ThreeTenABP,有非常详尽的解释。
推荐阅读
- mysql - MySQL:查找在一个日期(时间)有条目但在另一个日期(时间)没有条目的用户行
- css - 如何进行响应式列换行?
- java - 从 Java 访问 Kotlin 枚举
- ios - 在我的 iOS 应用程序中包含 HTTP(不是 HTTPS)URL 链接,我是否需要禁用应用程序传输安全性?
- c# - 将 Base64 转换为字符串会插入空格
- python - 如何使用python禁用windows上的printscreen键
- python - 如何提取 HDF5 数组矩阵的一部分及其对应的行属性
- firebase - Firebase Cloud Firestore 的成本优化模式:通过集合获取文档
- javascript - 每 3-4 个字符插入空格
- css - 设置背景混合模式和背景颜色在 HTML 电子邮件中不起作用