AlarmManager 在不同 API 的不同时间后触发

AlarmManager fires after different times on different API's

这是我第一次使用AlarmReciever。这是服务的一部分:

//Service
    this.context=this;
    Intent alarm = new Intent(this.context,AlarmReceiver.class);
    boolean alarmRunning =(PendingIntent.getBroadcast(this.context,0, alarm,PendingIntent.FLAG_NO_CREATE) != null);
    if(alarmRunning == false){
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this.context,0,alarm,0);
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(),15000,pendingIntent);
    }

我以为alarmManager.setRepeating中的15000是15秒。在我的 API 19 的 S4 mini 上是正确的。但是对于 API 23 的 S7,警报每分钟都会触发。有人知道这个问题吗?

这是我的日志:

08-15 10:54:15.949 11495-11522/com.example.entwicklung1.designtestapp D/BackgroundRunning::
08-15 10:55:15.619 11495-12452/com.example.entwicklung1.designtestapp D/BackgroundRunning::
08-15 10:56:15.619 11495-13407/com.example.entwicklung1.designtestapp D/BackgroundRunning::
08-15 10:57:15.629 11495-14288/com.example.entwicklung1.designtestapp D/BackgroundRunning::
08-15 10:58:15.629 11495-15193/com.example.entwicklung1.designtestapp D/BackgroundRunning::
08-15 11:00:00.039 11495-16907/com.example.entwicklung1.designtestapp D/BackgroundRunning::
08-15 11:00:15.599 11495-17149/com.example.entwicklung1.designtestapp D/BackgroundRunning::
08-15 11:01:15.619 11495-18085/com.example.entwicklung1.designtestapp D/BackgroundRunning::
08-15 11:02:15.659 11495-19040/com.example.entwicklung1.designtestapp D/BackgroundRunning::
08-15 11:03:58.049 11495-19601/com.example.entwicklung1.designtestapp D/BackgroundRunning::
08-15 11:06:11.419 11495-19878/com.example.entwicklung1.designtestapp D/BackgroundRunning::
08-15 11:11:11.349 11495-24547/com.example.entwicklung1.designtestapp D/BackgroundRunning::
08-15 11:16:11.449 11495-29123/com.example.entwicklung1.designtestapp D/BackgroundRunning::

正如我所见,它现在每隔几分钟就会触发一次。

来自新文档:

注意:从 API19 开始,所有重复的警报都是不准确的。如果您的应用程序需要精确的交付时间,那么它必须使用一次性精确警报,并如上所述重新安排每次时间。 targetSdkVersion 早于 API 19 的旧版应用程序将继续将所有警报(包括重复警报)视为精确警报。

那么如何获得相同的行为呢? 您可以使用 setExact 并通过 PendingIntent

重新设置 AlarmManager

自从 Alarm Manager 唤醒耗尽电池的设备后,Android 有一些新方法来触发待处理的 Intent。在 API 大于或等于 19 的设备上,如果两个或多个警报具有相似的时间来启动未决意图,则会一起触发警报,这样它就不必每次都唤醒设备警报。所以你必须做的新修改是放置这段代码:

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

在这行代码之后,放置:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(),15000,pendingIntent);

} else {
        alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(),15000,pendingIntent);
}

这里,如果Android API大于KITKAT,则使用setExact方法,如果不是,则像你一样正常设置闹钟。希望这个有用,一切顺利。