使用 setExact() 在每天的特定时间触发警报
Triggering an alarm at a specific time every day by using setExact()
我正在尝试每天在特定时间触发一次闹钟。但是和所有其他人一样,我使用 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();
}
}
}
广播接收器:
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);
}
}
广播观察者:
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);
}
}
}
once it fires it keeps on repeating itself after every 5 sec
您正在为给定的 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()
中的警报是多余的。这不是一个重复的警报,所以在它触发后取消它是没有意义的。
我正在尝试每天在特定时间触发一次闹钟。但是和所有其他人一样,我使用 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();
}
}
}
广播接收器:
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);
}
}
广播观察者:
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);
}
}
}
once it fires it keeps on repeating itself after every 5 sec
您正在为给定的 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()
中的警报是多余的。这不是一个重复的警报,所以在它触发后取消它是没有意义的。