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 进行比较。