AlarmManager 在第二个间隔完成之前触发
AlarmManager Triggers before second interval completes
我编写了一个每天在 5:22 上午运行的警报代码。该代码在第一个时间间隔内运行良好,但在第二个时间间隔内会在 24 小时前触发。
我在 MainActivity 的 onCreate()
方法中添加了警报代码,该代码在第一个间隔内运行完美,但在第一个间隔后,如果我打开 MainActivity,警报将再次触发并在我继续触发时继续触发打开主活动。例如,如果我打开 MainActivity 两次,警报将触发两次。
我在这里也提到了一些解决方案,但它们不像 marmor's answer 那样有效。
我也尝试检查是否使用 FLAG_NO_CREATE 标志设置了警报,但它仍然不起作用。
下面是我的代码。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, ServiceReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 11111, intent, 0);
Calendar calNow = Calendar.getInstance();
Calendar calSet = (Calendar) calNow.clone();
calSet.set(Calendar.HOUR_OF_DAY, 5);
calSet.set(Calendar.MINUTE, 11);
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
if(calSet.compareTo(calNow) <= 0){
//Today Set time passed, count to tomorrow
calSet.add(Calendar.DATE, 1);
}
alarmMgr.cancel(alarmIntent);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent); //1000 * 60 * 1440
}
我正在将服务运行到文本文件的时间记录下来。
编辑:
目标sdk版本为22
并且根据kolombo的建议我检查了日期并检查了我的if语句是否被执行。执行了 if 语句,我得到了明天的同一时间的日期。
我正在使用 Moto E 开发应用程序。
我已将项目文件 here 上传到 google 驱动器。
您需要通过服务上的 onStartCommand 函数 return START_NOT_STICKY。或者您必须在作业完成后停止它。或者您可以使用 IntentService 而不是 Service。闹钟正常。
public int onStartCommand(Intent intent, int flags, int startId){
try{
commitToFile("Start");
}catch (Exception e){}
try{
commitToFile("End");
}catch (Exception e){}
return START_NOT_STICKY;
}
你 returned 0,那是 START_STICKY_COMPATIBILITY。当您的服务第一次启动时您的警报响起并且 运行。当您重新启动应用程序时,您的服务也会重新启动,因为您没有停止它。如果您 return START_NOT_STICKY - 服务将不会重新启动。或者,如果您使用 IntentService,此服务会完成工作并自动完成。
每当您的 MainActivity 启动时,都会调用 onCreate(),因此您将以警报通知的多个实例结束。
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
意图 intent = new Intent(this, ServiceReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 11111, intent, 0);
Calendar calNow = Calendar.getInstance();
Calendar calSet = (Calendar) calNow.clone();
calSet.set(Calendar.HOUR_OF_DAY, 5);
calSet.set(Calendar.MINUTE, 11);
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
if(calSet.compareTo(calNow) <= 0){
//Today Set time passed, count to tomorrow
calSet.add(Calendar.DATE, 1);
}
alarmMgr.cancel(alarmIntent);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent); //1000 * 60 * 1440
将上面的代码放在 if
条件中,并在再次调用 onCreate 时将结果保存在 SharedPreferences(例如:calSet)中,只需从 getSharedPreferences 中获取值并与 calNow 进行比较。
我编写了一个每天在 5:22 上午运行的警报代码。该代码在第一个时间间隔内运行良好,但在第二个时间间隔内会在 24 小时前触发。
我在 MainActivity 的 onCreate()
方法中添加了警报代码,该代码在第一个间隔内运行完美,但在第一个间隔后,如果我打开 MainActivity,警报将再次触发并在我继续触发时继续触发打开主活动。例如,如果我打开 MainActivity 两次,警报将触发两次。
我在这里也提到了一些解决方案,但它们不像 marmor's answer 那样有效。
我也尝试检查是否使用 FLAG_NO_CREATE 标志设置了警报,但它仍然不起作用。
下面是我的代码。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, ServiceReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 11111, intent, 0);
Calendar calNow = Calendar.getInstance();
Calendar calSet = (Calendar) calNow.clone();
calSet.set(Calendar.HOUR_OF_DAY, 5);
calSet.set(Calendar.MINUTE, 11);
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
if(calSet.compareTo(calNow) <= 0){
//Today Set time passed, count to tomorrow
calSet.add(Calendar.DATE, 1);
}
alarmMgr.cancel(alarmIntent);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent); //1000 * 60 * 1440
}
我正在将服务运行到文本文件的时间记录下来。
编辑:
目标sdk版本为22
并且根据kolombo的建议我检查了日期并检查了我的if语句是否被执行。执行了 if 语句,我得到了明天的同一时间的日期。
我正在使用 Moto E 开发应用程序。
我已将项目文件 here 上传到 google 驱动器。
您需要通过服务上的 onStartCommand 函数 return START_NOT_STICKY。或者您必须在作业完成后停止它。或者您可以使用 IntentService 而不是 Service。闹钟正常。
public int onStartCommand(Intent intent, int flags, int startId){
try{
commitToFile("Start");
}catch (Exception e){}
try{
commitToFile("End");
}catch (Exception e){}
return START_NOT_STICKY;
}
你 returned 0,那是 START_STICKY_COMPATIBILITY。当您的服务第一次启动时您的警报响起并且 运行。当您重新启动应用程序时,您的服务也会重新启动,因为您没有停止它。如果您 return START_NOT_STICKY - 服务将不会重新启动。或者,如果您使用 IntentService,此服务会完成工作并自动完成。
每当您的 MainActivity 启动时,都会调用 onCreate(),因此您将以警报通知的多个实例结束。
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 意图 intent = new Intent(this, ServiceReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 11111, intent, 0);
Calendar calNow = Calendar.getInstance();
Calendar calSet = (Calendar) calNow.clone();
calSet.set(Calendar.HOUR_OF_DAY, 5);
calSet.set(Calendar.MINUTE, 11);
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
if(calSet.compareTo(calNow) <= 0){
//Today Set time passed, count to tomorrow
calSet.add(Calendar.DATE, 1);
}
alarmMgr.cancel(alarmIntent);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent); //1000 * 60 * 1440
将上面的代码放在 if
条件中,并在再次调用 onCreate 时将结果保存在 SharedPreferences(例如:calSet)中,只需从 getSharedPreferences 中获取值并与 calNow 进行比较。