Java 与x27之间的差异;setExact';和';设置报警时钟';

Java 与x27之间的差异;setExact';和';设置报警时钟';,java,android,alarm,Java,Android,Alarm,在我的应用程序中,应该在指定的时间触发警报,警报的目的是通过通知通知用户,我对获得不精确的结果感到失望。警报正在响,但不是在指定的时间。当设置警报和它应该熄灭的时间之间的时间很长时,这是系统性的。 为此,我使用了setExact(RTC\u唤醒、时间、意图)。经过多次尝试,我终于看到并尝试了setAlarmClock功能,一切正常 根据javadoc,setAlarmClock与setExact相同,只是它意味着RTC\u唤醒。在我看来,至少还有一个区别存在。有人知道吗?而且两人都打了非常相似的

在我的应用程序中,应该在指定的时间触发警报,警报的目的是通过
通知
通知用户,我对获得不精确的结果感到失望。警报正在响,但不是在指定的时间。当设置警报和它应该熄灭的时间之间的时间很长时,这是系统性的。 为此,我使用了
setExact(RTC\u唤醒、时间、意图)
。经过多次尝试,我终于看到并尝试了
setAlarmClock
功能,一切正常

根据javadoc,
setAlarmClock
setExact
相同,只是它意味着
RTC\u唤醒
。在我看来,至少还有一个区别存在。有人知道吗?

而且两人都打了非常相似的电话。如果对
setExact()
调用使用
RTC_WAKEUP
,唯一的区别是
AlarmClockInfo
类型的最终参数

在服务端,呼叫是在中接收的。在该方法的末尾,我们可以看到额外参数的不同之处:

@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);
}
@覆盖
公共无效集(int类型、长触发器时间、长窗口长度、长间隔、int标志、,
PendingEvent操作,工作源工作源,
AlarmManager.AlarmClockInfo(报警时钟){
final int callingUid=Binder.getCallingUid();
如果(工作源!=null){
getContext().enforcePermission(
android.Manifest.permission.UPDATE\u DEVICE\u STATS,
Binder.getCallingPid(),callingUid,“AlarmManager.set”);
}
//没有传入呼叫者可以从空闲或空闲请求唤醒
//允许空闲时不受限制——我们稍后将根据需要应用这些。
flags&=~(AlarmManager.FLAG\u唤醒\u从\u空闲
|AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED);
//只有系统才能使用标志_IDLE_,直到——这用于通知警报
//manager何时退出空闲模式,这仅适用于DeviceIdleController。
if(callingUid!=Process.SYSTEM\u UID){
flags&=~AlarmManager.FLAG\u IDLE\u UNTIL;
}
//如果调用者是一个核心系统组件,而不是代表其进行调用
//对于其他人,则始终设置允许\u而空闲\u不受限制。这意味着我们
//将允许这些警报在无定时的情况下正常关闭,即使在空闲时也是如此
//限制。
if(callingUid
如果有一个非空的
alarmClock
参数,则请求会在
FLAG\u STANDALONE
上获得
FLAG\u WAKE\u FROM\u IDLE
标志,这两种情况下都会得到。他的评论说:

报警标志:即使设备处于空闲状态,此报警也会唤醒设备。例如,这是闹钟的闹钟

如果你愿意的话,你可以——但就我所知,这就是区别。您的“正常”精确警报不会将设备从空闲状态唤醒,但使用setAlarmClock()设置的警报会唤醒设备。

,在Android 6.0(API级别23)中引入,为上述限制增加了进一步的限制:(TL;DR:only
setAlarmClock
在睡眠模式下触发,和)

打盹限制 打瞌睡时,以下限制适用于您的应用程序:[……]

  • 系统忽略尾流锁
  • 标准的
    AlarmManager
    报警(包括
    setExact()
    setWindow()
    )延迟到下一个维护窗口。
    • 如果需要设置打盹时触发的警报,请使用
      setAndAllowHileIDLE()
      setExactAndAllowHileIDLE()
    • 使用
      setAlarmClock()
      设置的报警将继续正常触发-系统在这些报警触发前不久将退出休眠状态。 [……]

设备进入低功率打盹状态,定期唤醒以执行其他报警等。

主要区别在于
setExact
不允许操作系统调整发送时间。它尽可能接近请求的触发时间。这不是文档所说的:当API中要求19以上的精确计时时,“setExact”应该取代“set”。据我所见,“尽可能接近请求的触发时间”可能长达近4分钟。两个连续的警报以1分钟的间隔发出,间隔为5分钟(非常精确的时间间隔)。你当然是对的。解释应来自此“标志\唤醒\来自\空闲”标志。我唯一感到遗憾的是,javaDoc具有误导性(它说,如果您希望您的报警准确,请使用不正确的“setExact”),并且此标志没有出现在javaDoc中。是的,似乎AlarmManager内部有
标志\u WAKE\u FROM\u IDLE
。这似乎与安卓棉花糖中引入的“打瞌睡模式”功能有关。公平地说,setExact()文档说“警报将尽可能地发送到请求的触发时间”。我想“尽可能”的定义可能会被曲解为包括“我现在更愿意节约电池”……我同意你的观点,你提出的声明将更接近现实,更少误导。说明报警设置为setA