AlarmManager RepeatingAlarm не срабатывает более одного раза

Итак, у меня есть фоновое обновление, которое пользователь может переключать в настройках. Вот код из активности Settings:

intent  = new Intent(context, UpdateScoresService.class);
recurringDownloadDaily = PendingIntent.getService(context,0,intent, 0);
recurringDownloadWeekly = PendingIntent.getService(context, 1, intent, 0);
 Preference.OnPreferenceChangeListener refreshListener = new Preference.OnPreferenceChangeListener() {
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    if(newValue.toString().equals("1")){ /* daily */
                        background_refresh.setSummary("Scores will be refreshed daily.");

                        AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
                        manager.cancel(recurringDownloadDaily);
                        manager.cancel(recurringDownloadWeekly);
                        Log.e("DAILY REFRESH", " ");
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTimeInMillis(System.currentTimeMillis());
                        calendar.set(Calendar.HOUR_OF_DAY,10);
                        calendar.set(Calendar.MINUTE,00);
                        if(calendar.before(Calendar.getInstance())){
                            Log.e("AFTER", "10 AM DAILY");
                            calendar.add(Calendar.DATE, 1);
                        }
                        manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, recurringDownloadDaily);
                    }else if(newValue.toString().equals("2")){ /* weekly */
                        Log.e("WEEKLY REFRESH", " ");
                        background_refresh.setSummary("Scores will be refreshed weekly.");
                        AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
                        manager.cancel(recurringDownloadDaily);
                        manager.cancel(recurringDownloadWeekly);
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTimeInMillis(System.currentTimeMillis());
                        calendar.set(Calendar.HOUR_OF_DAY,10);
                        calendar.set(Calendar.MINUTE,00);
                        if(calendar.before(Calendar.getInstance())){
                            Log.e("AFTER", "10 AM WEEKLY");
                            calendar.add(Calendar.DATE, 1);
                        }
                        manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, recurringDownloadWeekly);
                    }else{ /* manually */
                        background_refresh.setSummary("Scores will be refreshed manually.");
                        Log.e("MANUAL REFRESH", " ");
                        AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
                        manager.cancel(recurringDownloadDaily);
                        manager.cancel(recurringDownloadWeekly);
                    }
                    return true;
                }
            };
            background_refresh.setOnPreferenceChangeListener(refreshListener);

Если пользователь устанавливает ежедневный будильник, я ожидаю, что он будет обновляться каждое утро в 10:00. Для тестирования, когда я устанавливаю дату на следующий день и устанавливаю время на 9:59, будильник срабатывает около 10:00. И может постоянно менять дату и время на телефоне вручную, и он каждый раз срабатывает. Однако, похоже, если я установлю эту опцию и просто подожду до следующего дня, будильник может сработать, а может и не сработать. Я чувствую, что чаще всего этого не происходит.

У меня также есть этот код, чтобы узнать, когда устройство завершило загрузку, чтобы переназначить будильник после выключения и повторного включения устройства:

public void onReceive(Context context, Intent intent) {
        Log.e("Boot reciever", "a");
        if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
//            Toast.makeText(context, "Boot Reciever", Toast.LENGTH_SHORT).show();
            Log.e("Boot reciever", "b");
            SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
            intent1  = new Intent(context, UpdateScoresService.class);
            recurringDownload = PendingIntent.getService(context,0,intent1, 0);

            String refreshRate = sharedPreferences.getString("background_refresh", "1");

            if(refreshRate.equals("1")){ /* daily */
                daily(context);
            }else if(refreshRate.equals("2")){ /* weekly */
                weekly(context);
            }else { /* manually */
                manually(context);
            }

        }
    }

    public void daily(Context context){
        Log.e("DAILY REFRESH", "BRUH!");
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY,10);
        calendar.set(Calendar.MINUTE,00);
        if(calendar.before(Calendar.getInstance())){
            Log.e("AFTER", "10 AM WEEKLY");
            calendar.add(Calendar.DATE, 1);
        }
        AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        manager.setInexactRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY, recurringDownload);
    }
    public void weekly(Context context){
        Log.e("WEEKLY REFRESH", "BRUH!");
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY,10);
        calendar.set(Calendar.MINUTE,00);
        if(calendar.before(Calendar.getInstance())){
            Log.e("AFTER", "10 AM WEEKLY");
            calendar.add(Calendar.DATE, 1);
        }
        AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        manager.setInexactRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY * 7, recurringDownload);
    }

    public void manually(Context context){
        Log.e("MANUAL REFRESH", "BRUH!");
        AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        manager.cancel(recurringDownload);
    }

И, насколько я могу судить, это тоже работает, если я выключаю телефон в 9:55 и снова загружаю его, служба все еще работает.

Проблема в том, что он не работает на следующий день или несколько дней. Я не совсем уверен, почему, может быть, служба убивается в фоновом режиме? Я думал добавить тот же код в onResume MainActivity, чтобы перепланировать будильник, но это кажется немного чрезмерным, и я должен иметь возможность заставить его работать последовательно, не делая этого.


person user2923535    schedule 01.11.2016    source источник


Ответы (1)


Не уверен, но проверьте следующие пункты:

  1. Созданы два уникальных будильника с идентификаторами 0 и 1, но при завершении загрузки перезапускается только один будильник с идентификатором 0.
  2. При тестировании с повторяющимися сигналами тревоги с изменением даты туда и обратно могут возникнуть проблемы. Так как будильник для этого дня может сработать, а позже вы перейдете на предыдущую дату, он не будет срабатывать для этого дня еще раз, пока не перезапустите его.
  3. После завершения загрузки или назначения каких-либо сигналов тревоги вы должны отменить предыдущие сигналы тревоги для этого ожидающего намерения, прежде чем назначать ему.
  4. Ваша служба не убита, потому что они не запущены, поскольку ожидающее намерение должно быть запущено службой.

Если вы все еще сталкиваетесь с проблемой, проверьте это блог. (Не уверен, где что-то пошло не так, поэтому публикую URL моего блога для ссылок)

person chiru    schedule 01.11.2016
comment
Для 1, о, ты прав, хм, я обязательно это изменю. Для 2 я использую базу данных для регистрации изменений, поэтому я просто делаю резервную копию базы данных, и когда я закончу с таким тестированием, я заменяю измененную базу данных резервной копией. Для 3 я точно забыл это сделать. - person user2923535; 01.11.2016