Запуск будильника в определенное время каждый день с помощью setExact () - PullRequest
0 голосов
/ 09 ноября 2018

Я пытаюсь активировать будильник один раз в определенное время каждый день. Но, как и все остальные, я использую setExact() вместо setRepeating(). Тревога срабатывает в нужное время. Но как только он срабатывает, он продолжает повторяться через каждые 5 секунд. Как я могу запустить его только один раз в день в определенное время? Вот мой код:

MainActivity.java:

public class MainActivity extends AppCompatActivity implements Observer {

    private AlarmManager alarmManager = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        BroadcastObserver.getInstance().addObserver(this);
    }

    @Override
    public void update(Observable o, Object arg) {
        Log.e("MainActivity", "Alarm set through observer");
        cancelAlarm();
        setAlarm();
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (!checkAlarm()) {
            setAlarm();
        }

    }

    public void setAlarm() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 14);
        calendar.set(Calendar.MINUTE, 13);
        calendar.set(Calendar.SECOND, 0);
        alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(this, MyReceiver.class);
        intent.setAction(MyReceiver.ACTION_RECEIVER);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
    }

    private boolean checkAlarm() {
        Intent intent = new Intent(this, MyReceiver.class);
        intent.setAction(MyReceiver.ACTION_RECEIVER);
        boolean isSet = PendingIntent.getBroadcast(this, 1001, intent, PendingIntent.FLAG_NO_CREATE) != null;
        Log.e("MainActivity", isSet + " :Alarm is set");
        return isSet;
    }

    @Override
    protected void onStop() {
        super.onStop();
        cancelAlarm();
    }

    private void cancelAlarm() {
        Intent intent = new Intent(this, MyReceiver.class);
        intent.setAction(MyReceiver.ACTION_RECEIVER);
        final PendingIntent pendingIntent =
                PendingIntent.getBroadcast(MainActivity.this, 1001, intent,
                        PendingIntent.FLAG_NO_CREATE);
        if (pendingIntent != null) {
            alarmManager.cancel(pendingIntent);
            pendingIntent.cancel();
        }
    }
}

BroadcastReceiver:

public class MyReceiver extends BroadcastReceiver {

    public static final String ACTION_RECEIVER = "Receiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("MainActivity", "triggered");
        BroadcastObserver.getInstance().updateValue(intent);
    }
}

BroadcastObserver:

public class BroadcastObserver extends Observable {
    private static BroadcastObserver instance = new BroadcastObserver();

    public static BroadcastObserver getInstance(){
        return instance;
    }

    private BroadcastObserver(){}

    public void updateValue(Object data) {
        synchronized (this) {
            setChanged();
            notifyObservers(data);
        }
    }
}

1 Ответ

0 голосов
/ 09 ноября 2018

как только он срабатывает, он продолжает повторяться через каждые 5 секунд

Вы устанавливаете будильник на 14:13 для данного дня. Когда срабатывает сигнализация, Observer уведомляется и устанавливает точный тот же сигнал (для 14:13).

В этот момент мы миновали 14:13, поэтому сигнализация сработает немедленно, снова уведомив Observer, что приведет к бесконечному циклу вышеуказанных шагов.

Самым простым решением может быть проверка времени при установке будильника, а если он в прошлом, то добавление дня к нему:

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 14);
calendar.set(Calendar.MINUTE, 13);
calendar.set(Calendar.SECOND, 0);

if (calendar.before(Calendar.getInstance())) {
    calendar.add(Calendar.DAY_OF_YEAR, 1);
}

Чтобы избежать утечек памяти, необходимо удалить Observer, когда это необходимо:

@Override
protected void onDestroy() {
    BroadcastObserver.getInstance().deleteObserver(this);
    super.onDestroy();
}

Кроме того, отмена тревоги в update() является избыточной. Это не повторяющийся сигнал тревоги, поэтому нет смысла отменять его после срабатывания.

...