Android的闹钟管理器错误的时期

时间:2016-09-18 14:31:28

标签: android alarmmanager

我正在为我的应用创建AlarmManager,以便在不同时段发送短信。当我为AlarmManager花费时间例如5分钟时,它几乎立即醒来大约1-2次,但在此之后它工作正常。在改变周期值后,情境会重复。我认为停止AlarmManager或设置转发器是错误的。

这是我的makeAlarm功能:

  private void makeAlarm() {
    cancelAlarm();

    Intent i = new Intent(this, SmsAlarmReceiver.class);

    PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), SmsAlarmReceiver.REQUEST_CODE,
            i, PendingIntent.FLAG_UPDATE_CURRENT);

    long firstMillis = System.currentTimeMillis();

    SharedPreferences refreshSettings = getSharedPreferences("com.example.xd720p.sensorcontroller_09082016",
            Context.MODE_PRIVATE);

    double refreshForTValue = Double.valueOf(refreshSettings.getString("tempPeriod", "30"));

    if (refreshForTValue <= 0 ) {
        cancelAlarm();
    } else {
        long period = Math.round(refreshForTValue * 60 * 1000);
        AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarm.setRepeating(AlarmManager.RTC_WAKEUP, firstMillis,
                firstMillis + period, pendingIntent);
    }
}

这是我的cancelAlarm功能:

  private void cancelAlarm() {
    try {
        Intent i = new Intent(this, SmsAlarmReceiver.class);
        PendingIntent pIntent = PendingIntent.getBroadcast(this.getApplicationContext(), SmsAlarmReceiver.REQUEST_CODE,
                i, 0);

        AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);

        alarm.cancel(pIntent);
        pIntent.cancel();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

这是我的SmsAlarmReceiver类,它扩展了BroadcastReceiver

  public class SmsAlarmReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 322;


  @Override
  public void onReceive(Context context, Intent intent) {

      Intent i = new Intent(context, SmsSenderService.class);
      context.startService(i);
  }
}

我在onCreate MainActivity方法中创建了闹钟。当我更改周期值时,我也会停止警报并制作新的警报。此值存储在SharedPreferences中,因此我尝试在onSharedPreferenceChanged中重新创建闹钟,但在我的情境中没有任何意义。

1 个答案:

答案 0 :(得分:1)

最后,我解决了!这是我在makeAlarm()函数中的解决方案:

    private void makeAlarm() {
    cancelAlarm();

    Intent i = new Intent(this, SmsAlarmReceiver.class);

    PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), SmsAlarmReceiver.REQUEST_CODE,
            i, PendingIntent.FLAG_CANCEL_CURRENT);

    SharedPreferences refreshSettings = getSharedPreferences("com.example.xd720p.sensorcontroller_09082016",
            Context.MODE_PRIVATE);

    double refreshForTValue = 0;


    refreshForTValue = Double.valueOf(refreshSettings.getString("tempPeriod", "30"));


    if (refreshForTValue <= 0 ) {
        cancelAlarm();
    } else {
        long period = Math.round(refreshForTValue * 60 * 1000);
        AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
        long firstMillis = System.currentTimeMillis();
        alarm.setRepeating(AlarmManager.RTC_WAKEUP, firstMillis + period,
                period, pendingIntent);
    }
}
  1. 如您所见,我更改了setRepeating()个参数。问题在于第二个参数不仅适用于期间的设定开始时间,而且还会在开始时间内唤醒警报。因此,如果我们不想立即唤醒警报,我们需要添加期间值。而第三个参数只是一个重复周期,所以我们需要删除开始时间。您可以在此处的示例中阅读此内容: https://developer.android.com/training/scheduling/alarms.html

  2. PendingIntent.getBroadcast()中,我们需要将标记从 FLAG_UPDATE_CURRENT 更改为 FLAG_CANCEL_CURRENT 。我无法准确解释原因,但根据文档,当我们设置 UPDATE 标志时,某些已更改的属性将被忽略。因此,警报首先会在过去的一段时间内醒来。但 CANCEL_FLAG 允许我们更换属性并用新时段唤醒警报。如果我的解释不正确,我很抱歉:正如我所说,我并不完全理解这一刻。如果有人给出了很好的解释,我会很高兴的。