'setExact' 和 'setAlarmClock' 之间的区别
Difference between 'setExact' and 'setAlarmClock'
在我应该在指定时间触发警报的应用程序中,警报的目的是通过 Notification
通知用户,我对获得不精确的结果感到绝望。闹钟响了,但不是在指定的时间。当警报设置和它应该响起的时间之间的时间很长时,这是系统性的。
为此,我使用了 setExact(RTC_WAKEUP,time,intent)
。经过多次尝试使其工作,我终于看到并尝试了 setAlarmClock
功能,一切顺利!!
根据 javadoc,setAlarmClock
与 setExact
相同,只是它暗含 RTC_WAKEUP
。据我所知,至少存在另一个差异。有人知道吗?
setExact()
and setAlarmClock()
both make very similar calls to setImpl()
。如果您将 RTC_WAKEUP
用于 setExact()
调用,唯一的区别是类型为 AlarmClockInfo
.
的最终参数
在服务端,在set()接到电话。在该方法的末尾,我们可以看到额外参数的不同之处:
@Override
public void set(int type, long triggerAtTime, long windowLength, long interval, int flags,
PendingIntent operation, WorkSource workSource,
AlarmManager.AlarmClockInfo alarmClock) {
final int callingUid = Binder.getCallingUid();
if (workSource != null) {
getContext().enforcePermission(
android.Manifest.permission.UPDATE_DEVICE_STATS,
Binder.getCallingPid(), callingUid, "AlarmManager.set");
}
// No incoming callers can request either WAKE_FROM_IDLE or
// ALLOW_WHILE_IDLE_UNRESTRICTED -- we will apply those later as appropriate.
flags &= ~(AlarmManager.FLAG_WAKE_FROM_IDLE
| AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED);
// Only the system can use FLAG_IDLE_UNTIL -- this is used to tell the alarm
// manager when to come out of idle mode, which is only for DeviceIdleController.
if (callingUid != Process.SYSTEM_UID) {
flags &= ~AlarmManager.FLAG_IDLE_UNTIL;
}
// If the caller is a core system component, and not calling to do work on behalf
// of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED. This means we
// will allow these alarms to go off as normal even while idle, with no timing
// restrictions.
if (callingUid < Process.FIRST_APPLICATION_UID && workSource == null) {
flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
}
// If this is an exact time alarm, then it can't be batched with other alarms.
if (windowLength == AlarmManager.WINDOW_EXACT) {
flags |= AlarmManager.FLAG_STANDALONE;
}
// If this alarm is for an alarm clock, then it must be standalone and we will
// use it to wake early from idle if needed.
if (alarmClock != null) {
flags |= AlarmManager.FLAG_WAKE_FROM_IDLE | AlarmManager.FLAG_STANDALONE;
}
setImpl(type, triggerAtTime, windowLength, interval, operation,
flags, workSource, alarmClock, callingUid);
}
如果存在非空 alarmClock
参数,请求将在 FLAG_STANDALONE
之上获得 FLAG_WAKE_FROM_IDLE
标志,在这两种情况下您都会获得。 FLAG_WAKE_FROM_IDLE
的评论说:
Flag for alarms: this alarm would like to wake the device even if it is idle. This is, for example, an alarm for an alarm clock.
如果你愿意,你可以 dig into the usage of FLAG_WAKE_FROM_IDLE
-- 但据我所知,这就是区别。您的 "normal" 确切的闹钟不会将设备从空闲状态唤醒,但使用 setAlarmClock() 设置的闹钟会。
Doze mode, introduced in Android 6.0 (API level 23), adds further restrictions to those outlined above: (TL;DR: only setAlarmClock
triggers in doze mode, and )
Doze restrictions
The following restrictions apply to your apps while in Doze: [...]
- The system ignores wake locks.
- Standard
AlarmManager
alarms (including setExact()
and setWindow()
) are deferred to the next maintenance window.
- If you need to set alarms that fire while in Doze, use
setAndAllowWhileIdle()
or setExactAndAllowWhileIdle()
.
- Alarms set with
setAlarmClock()
continue to fire normally — the system exits Doze shortly before those alarms fire.
[...]
设备进入低功耗休眠状态,并定期唤醒以执行其他警报等
在我应该在指定时间触发警报的应用程序中,警报的目的是通过 Notification
通知用户,我对获得不精确的结果感到绝望。闹钟响了,但不是在指定的时间。当警报设置和它应该响起的时间之间的时间很长时,这是系统性的。
为此,我使用了 setExact(RTC_WAKEUP,time,intent)
。经过多次尝试使其工作,我终于看到并尝试了 setAlarmClock
功能,一切顺利!!
根据 javadoc,setAlarmClock
与 setExact
相同,只是它暗含 RTC_WAKEUP
。据我所知,至少存在另一个差异。有人知道吗?
setExact()
and setAlarmClock()
both make very similar calls to setImpl()
。如果您将 RTC_WAKEUP
用于 setExact()
调用,唯一的区别是类型为 AlarmClockInfo
.
在服务端,在set()接到电话。在该方法的末尾,我们可以看到额外参数的不同之处:
@Override
public void set(int type, long triggerAtTime, long windowLength, long interval, int flags,
PendingIntent operation, WorkSource workSource,
AlarmManager.AlarmClockInfo alarmClock) {
final int callingUid = Binder.getCallingUid();
if (workSource != null) {
getContext().enforcePermission(
android.Manifest.permission.UPDATE_DEVICE_STATS,
Binder.getCallingPid(), callingUid, "AlarmManager.set");
}
// No incoming callers can request either WAKE_FROM_IDLE or
// ALLOW_WHILE_IDLE_UNRESTRICTED -- we will apply those later as appropriate.
flags &= ~(AlarmManager.FLAG_WAKE_FROM_IDLE
| AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED);
// Only the system can use FLAG_IDLE_UNTIL -- this is used to tell the alarm
// manager when to come out of idle mode, which is only for DeviceIdleController.
if (callingUid != Process.SYSTEM_UID) {
flags &= ~AlarmManager.FLAG_IDLE_UNTIL;
}
// If the caller is a core system component, and not calling to do work on behalf
// of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED. This means we
// will allow these alarms to go off as normal even while idle, with no timing
// restrictions.
if (callingUid < Process.FIRST_APPLICATION_UID && workSource == null) {
flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
}
// If this is an exact time alarm, then it can't be batched with other alarms.
if (windowLength == AlarmManager.WINDOW_EXACT) {
flags |= AlarmManager.FLAG_STANDALONE;
}
// If this alarm is for an alarm clock, then it must be standalone and we will
// use it to wake early from idle if needed.
if (alarmClock != null) {
flags |= AlarmManager.FLAG_WAKE_FROM_IDLE | AlarmManager.FLAG_STANDALONE;
}
setImpl(type, triggerAtTime, windowLength, interval, operation,
flags, workSource, alarmClock, callingUid);
}
如果存在非空 alarmClock
参数,请求将在 FLAG_STANDALONE
之上获得 FLAG_WAKE_FROM_IDLE
标志,在这两种情况下您都会获得。 FLAG_WAKE_FROM_IDLE
的评论说:
Flag for alarms: this alarm would like to wake the device even if it is idle. This is, for example, an alarm for an alarm clock.
如果你愿意,你可以 dig into the usage of FLAG_WAKE_FROM_IDLE
-- 但据我所知,这就是区别。您的 "normal" 确切的闹钟不会将设备从空闲状态唤醒,但使用 setAlarmClock() 设置的闹钟会。
Doze mode, introduced in Android 6.0 (API level 23), adds further restrictions to those outlined above: (TL;DR: only setAlarmClock
triggers in doze mode, and
Doze restrictions
The following restrictions apply to your apps while in Doze: [...]
- The system ignores wake locks.
- Standard
AlarmManager
alarms (includingsetExact()
andsetWindow()
) are deferred to the next maintenance window.
- If you need to set alarms that fire while in Doze, use
setAndAllowWhileIdle()
orsetExactAndAllowWhileIdle()
.- Alarms set with
setAlarmClock()
continue to fire normally — the system exits Doze shortly before those alarms fire. [...]
设备进入低功耗休眠状态,并定期唤醒以执行其他警报等