警报不会准确触发,有时根本不会触发
Alarm doesn't fire presicely and sometimes not at all
我正在尝试制作一个在用户选择的时间触发的警报。但是我注意到闹钟永远不会在选定的那一分钟响起。 IE。如果用户从 TimePicker 对话框中选择 8:30,警报通常会在 8:30 分钟内的某处触发,有时会延迟一分钟以上触发。此外,有时警报根本不会触发。目标是更新当前警报,以便它不会总是创建新警报。我是 Android 警报服务的新手,所以我希望有人能看一看。这是一些代码:
这个方法在我的onCreate中调用
private void initAlarmService() {
calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
ComponentName receiver = new ComponentName(getContext(), AlarmReceiver.class);
pm = getContext().getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
alarmIntent = new Intent(getContext(), AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(getContext(), 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
manager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
}
选择时间时调用此方法:
private void setTime(int hour, int minute) {
if(sharedPreferences.contains("ALARM_PREF")){
manager.cancel(pendingIntent);
}
sharedPreferences.edit().putString("ALARM_PREF", ""+hour + ":" +minute).apply();
//set date object time to picker value
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
//interval = 1000 * 60 * 60 * 24
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTime().getTime(), interval, pendingIntent);
//This just outputs to a textview
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm a");
time = sdf.format(calendar.getTime().getTime());
alarmText.setText(time);
calendar.setTimeInMillis(System.currentTimeMillis());
}
如果您描述的行为出现在 API 19+ 设备上,AlarmManager
documentation 的这篇注释可能会解释原因:
Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS
will shift alarms in order to minimize wakeups and battery use. There
are new APIs to support applications which need strict delivery
guarantees; see setWindow(int, long, long, PendingIntent) and
setExact(int, long, PendingIntent). Applications whose
targetSdkVersion is earlier than API 19 will continue to see the
previous behavior in which all alarms are delivered exactly when
requested.
在您的情况下,您需要切换到使用 setExact()
。遗憾的是没有setExactRepeating()
,因此您必须在收到第一个警报时再次手动设置。
我正在尝试制作一个在用户选择的时间触发的警报。但是我注意到闹钟永远不会在选定的那一分钟响起。 IE。如果用户从 TimePicker 对话框中选择 8:30,警报通常会在 8:30 分钟内的某处触发,有时会延迟一分钟以上触发。此外,有时警报根本不会触发。目标是更新当前警报,以便它不会总是创建新警报。我是 Android 警报服务的新手,所以我希望有人能看一看。这是一些代码:
这个方法在我的onCreate中调用
private void initAlarmService() {
calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
ComponentName receiver = new ComponentName(getContext(), AlarmReceiver.class);
pm = getContext().getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
alarmIntent = new Intent(getContext(), AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(getContext(), 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
manager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
}
选择时间时调用此方法:
private void setTime(int hour, int minute) {
if(sharedPreferences.contains("ALARM_PREF")){
manager.cancel(pendingIntent);
}
sharedPreferences.edit().putString("ALARM_PREF", ""+hour + ":" +minute).apply();
//set date object time to picker value
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
//interval = 1000 * 60 * 60 * 24
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTime().getTime(), interval, pendingIntent);
//This just outputs to a textview
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm a");
time = sdf.format(calendar.getTime().getTime());
alarmText.setText(time);
calendar.setTimeInMillis(System.currentTimeMillis());
}
如果您描述的行为出现在 API 19+ 设备上,AlarmManager
documentation 的这篇注释可能会解释原因:
Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.
在您的情况下,您需要切换到使用 setExact()
。遗憾的是没有setExactRepeating()
,因此您必须在收到第一个警报时再次手动设置。