Почему onReceive() вызывается дважды в этой настройке Alarm?
Я создаю приложение для шагомера Android, которое отправляет данные в базу данных SQLite с 30-минутными интервалами с помощью AlarmManager; если телефон выключен, когда предполагается передача, он выполнит передачу сразу после включения телефона.
(30 минут для тестирования - фактический интервал будет 1 неделя).
Мне сказали, что тревоги не будут сохраняться, если я не использую "intent.action.BOOT_COMPLETED" в манифесте, поэтому я добавил это в качестве фильтра для моего класса Alarm.java.
Мой код для установки будильника (в MainActivity.java) выглядит следующим образом:
public void insertData(View view) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
long time= System.currentTimeMillis();
Date d = new Date(time);
editor.putLong("alarmtime", time); //the next ring time for the alarm is put in SharedPreferences
editor.apply();
Intent intent = new Intent(this, Alarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC, time, AlarmManager.INTERVAL_DAY, pendingIntent);
Toast.makeText(MainActivity.this, "Alarm Set", Toast.LENGTH_LONG).show();
}
Код в классе Alarm.java (который расширяет BroadcastReceiver) выглядит следующим образом:
Context context; //plus other declared variables
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
preferences = context.getSharedPreferences("MyPreferences", context.MODE_PRIVATE);
editor = preferences.edit();
long startedtime = preferences.getLong("alarmtime", 0); //get the next ring time
Date nextRingTime = new Date(startedtime);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
String action = intent.getAction();
//sometimes the onReceive() is called by the phone turning on
if (action != null && action.equals(Intent.ACTION_BOOT_COMPLETED)) {
//if phone turned on again before the alarm, just re-create the alarm for the same time, don't transfer data
Date currenttime = new Date(System.currentTimeMillis());
if ((currenttime.compareTo(nextRingTime) < 0)) {
Intent newintent = new Intent(context, Alarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0,
newintent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC, startedtime, AlarmManager.INTERVAL_HALF_HOUR, pendingIntent);
return;
}
else if ((currenttime.compareTo(nextRingTime) > 0)) {
//if the phone was off when the alarm was supposed to make the transfer, set the alarm to the next intended ring time and insert data to db immediately
Calendar d = Calendar.getInstance();
d.setTime(nextRingTime);
d.add(Calendar.MINUTE, 30);
long newtime = d.getTimeInMillis();
Intent newintent = new Intent(context, Alarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0,
newintent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC, newtime, AlarmManager.INTERVAL_HALF_HOUR, pendingIntent);
}
}
myDb = new DatabaseHelper(context);
// code for inserting data into database
//finally, update next intended ring time in SharedPreferences now that this particular transfer is done:
Calendar c = Calendar.getInstance();
c.setTime(nextRingTime);
c.add(Calendar.MINUTE, 30);
Log.v("insertdone, alarrm now", c.getTime().toString());
long nexttime = c.getTimeInMillis();
editor.putLong("alarmtime", nextime);
editor.apply();
}
К сожалению, если телефон выключен во время запланированного будильника, когда я включаю его потом, он вызывает ДВАЖДЫ () ДВАЖДЫ, что означает, что он вставляет данные дважды.
Как это можно остановить?
Решением может быть использование RTC_WAKEUP, но я действительно не хочу этого делать, если только это не будет последним средством.
NB У меня есть отдельный класс bootBroadcastReceiver, который использует "intent.action.BOOT_COMPLETED" для перезапуска службы шагомера, и мне интересно, не вызывает ли проблемы запуск двух разных вещей при загрузке...