Android setAlarmClock 立即触发

Android setAlarmClock triggering immediately

我创建了一个简单的应用程序来试用 setAlarmClock()MainActivity 中只有一个按钮,单击时会调用 setAlarm

代码如下

MainActivity

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "alarmclock.MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void setAlarm(View view) {
        Context context = getApplicationContext();
        Intent intent = new Intent(context, AlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

        long nextTrigger = SystemClock.elapsedRealtime()+10*1000;
        Log.i(TAG, SystemClock.elapsedRealtime() + ": scheduling next alarm at " + nextTrigger);

        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

        AlarmManager.AlarmClockInfo ac = new AlarmManager.AlarmClockInfo(nextTrigger, null);
        alarmManager.setAlarmClock(ac, pendingIntent);
    }
}

AlarmReceiver

public class AlarmReceiver extends BroadcastReceiver {
    private static final String TAG = "alarmclock.AlarmReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, SystemClock.elapsedRealtime() + " in AlarmReceiver onReceive()");
    }
}

我基本上是在 10 秒后触发警报,但由于某种原因它立即触发。

2020-09-21 22:09:56.664 17910-17910/com.example.alarmclock I/alarmclock.MainActivity: 3362358: scheduling next alarm at 3372358
2020-09-21 22:09:56.687 17910-17910/com.example.alarmclock I/alarmclock.AlarmReceiver: 3362382 in AlarmReceiver onReceive()

如果我使用 setExactAndAllowWhileIdle 相同的代码似乎工作正常。但我特别想尝试 setAlarmClock.

AlarmClockInfo 需要墙时间:

time at which the underlying alarm is triggered in wall time milliseconds since the epoch

但您正在使用 elapsedRealtime() 时间,因此请使用 System.currentTimeMillis 解决问题。

我从SystemClock.elapsedRealtime()改成System.currentTimeMillis()后就成功了。

long nextTrigger = System.currentTimeMillis()+10*1000

在更详细地阅读 documentation 之后,我意识到 AlarmClockInfo 构造函数的第一个参数采用

long: time at which the underlying alarm is triggered in wall time milliseconds since the epoch

这是System.currentTimeMillis()给出的。

另一方面,SystemClock.elapsedRealtime() returns

time since the system was booted...

自纪元以来,这将始终比墙上时间小得多。结果,立即安排了警报,因为

If the stated trigger time is in the past, the alarm will be triggered immediately.