代码之家  ›  专栏  ›  技术社区  ›  sagar suri

使用setExact()在每天的特定时间触发警报

  •  1
  • sagar suri  · 技术社区  · 7 年前

    setExact() setRepeating() . 警报在正确的时间发出。但一旦它开火,它每5秒就会重复一次。我怎么能在一天中的某个特定时间触发一次呢?这是我的密码:

    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);
            }
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   earthw0rmjim Abhinav Das    7 年前

    您正在为给定的一天设置14:13的闹钟。当警报触发 Observer 相同的 警报(14:13)。

    现在我们已经过了14:13,所以警报会立即启动,通知 观察员

    最简单的解决方案可能是在设置警报时检查时间,如果是过去的时间,则添加一天:

    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);
    }
    

    为了避免内存泄漏,您需要删除 观察员 适当时:

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

    update() 是多余的。这不是一个重复的警报,所以在它触发后取消它是没有意义的。