Почему 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" для перезапуска службы шагомера, и мне интересно, не вызывает ли проблемы запуск двух разных вещей при загрузке...

0 ответов

Другие вопросы по тегам