Android 设置较长时间后 AlarmManager 不工作
Android AlarmManager not working when set for longer time
在我的应用程序中,我尝试使用以下代码设置闹钟:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2016);
calendar.set(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 1);
calendar.set(Calendar.MILLISECOND, 1);
Intent intent = new Intent(G.context, AlarmService.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext, 1010, intent, PendingIntent.FLAG_UPDATE_CURRENT);
G.alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
当我将闹钟设置为 1 分钟或更晚时有效,但当我将闹钟设置为 30 或 40 分钟后时无效。虽然我有 30 分钟不在 phone 上,但 30 分钟后闹钟没有响起,而当 phone 屏幕打开时,闹钟响了...
如有任何帮助,我们将不胜感激。
因为 API 19 set()
被视为不准确,可能会延迟。如果你真的需要一个精确的警报,你应该使用 setExact()(自 API 19 起可用)代替:
Note: Beginning in API 19, the trigger time passed to this method is
treated as inexact: the alarm will not be delivered before this time,
but may be deferred and delivered some time later. The OS will use
this policy in order to "batch" alarms together across the entire
system, minimizing the number of times the device needs to "wake up"
and minimizing battery use. In general, alarms scheduled in the near
future will not be deferred as long as alarms scheduled far in the
future.
此更改发生在 19 岁以上的设备上(很明显),但也只有当 APK 的 target API 为 19 岁以上时,您才可以
- 将目标 API 更改为 18
- 或使用Build.VERSION.SDK_INT了解使用哪种方法。
此外,当您使用 *_WAKE_UP
闹钟时,闹钟管理器保证设备将唤醒足够长的时间来执行接收器的方法,但不会启动它可能启动的服务:
The Alarm Manager holds a CPU wake lock as long as the alarm
receiver's onReceive() method is executing. This guarantees that the
phone will not sleep until you have finished handling the broadcast.
Once onReceive() returns, the Alarm Manager releases this wake lock.
This means that the phone will in some cases sleep as soon as your
onReceive() method completes. If your alarm receiver called
Context.startService(), it is possible that the phone will sleep
before the requested service is launched.
支持 v4 库提供了一个有用的帮助程序 class 来处理这种情况:WakefulBroadcastReceiver
在您的情况下,由于您使用的是服务待定意图,我不确定唤醒保证适用什么。
好的,那是因为在很长一段时间后(比方说超过 5 分钟)你的应用程序被暂停,然后 phone 是 "asleep" 并锁定屏幕。当您解锁它时,您会收到警报,因为它已排队。
要解决此问题,您需要实施唤醒锁并将其权限添加到您的清单文件中。
根据 Google 文档 "A wake lock is a mechanism to indicate that your application needs to have the device stay on."
这是您必须在清单中添加的行:
<uses-permission android:name="android.permission.WAKE_LOCK" />
您需要在 BroadcastReceiver 的 onReceive() 方法中实现此对象。您可以按照本教程使用您需要的所有内容。
https://www.javacodegeeks.com/2012/09/android-alarmmanager-tutorial.html
此外,请注意,您将保留设备 "awake",因此您将保留影响电池寿命的 phone 处理,但即使锁屏了
希望对您有所帮助!
我使用服务
public class AlarmService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onStart(Intent intent, int startid) {
//This is my Code and set Alarm
stopSelf();
}
}
在我的应用程序中,我尝试使用以下代码设置闹钟:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2016);
calendar.set(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 1);
calendar.set(Calendar.MILLISECOND, 1);
Intent intent = new Intent(G.context, AlarmService.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext, 1010, intent, PendingIntent.FLAG_UPDATE_CURRENT);
G.alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
当我将闹钟设置为 1 分钟或更晚时有效,但当我将闹钟设置为 30 或 40 分钟后时无效。虽然我有 30 分钟不在 phone 上,但 30 分钟后闹钟没有响起,而当 phone 屏幕打开时,闹钟响了...
如有任何帮助,我们将不胜感激。
因为 API 19 set()
被视为不准确,可能会延迟。如果你真的需要一个精确的警报,你应该使用 setExact()(自 API 19 起可用)代替:
Note: Beginning in API 19, the trigger time passed to this method is treated as inexact: the alarm will not be delivered before this time, but may be deferred and delivered some time later. The OS will use this policy in order to "batch" alarms together across the entire system, minimizing the number of times the device needs to "wake up" and minimizing battery use. In general, alarms scheduled in the near future will not be deferred as long as alarms scheduled far in the future.
此更改发生在 19 岁以上的设备上(很明显),但也只有当 APK 的 target API 为 19 岁以上时,您才可以
- 将目标 API 更改为 18
- 或使用Build.VERSION.SDK_INT了解使用哪种方法。
此外,当您使用 *_WAKE_UP
闹钟时,闹钟管理器保证设备将唤醒足够长的时间来执行接收器的方法,但不会启动它可能启动的服务:
The Alarm Manager holds a CPU wake lock as long as the alarm receiver's onReceive() method is executing. This guarantees that the phone will not sleep until you have finished handling the broadcast. Once onReceive() returns, the Alarm Manager releases this wake lock. This means that the phone will in some cases sleep as soon as your onReceive() method completes. If your alarm receiver called Context.startService(), it is possible that the phone will sleep before the requested service is launched.
支持 v4 库提供了一个有用的帮助程序 class 来处理这种情况:WakefulBroadcastReceiver
在您的情况下,由于您使用的是服务待定意图,我不确定唤醒保证适用什么。
好的,那是因为在很长一段时间后(比方说超过 5 分钟)你的应用程序被暂停,然后 phone 是 "asleep" 并锁定屏幕。当您解锁它时,您会收到警报,因为它已排队。 要解决此问题,您需要实施唤醒锁并将其权限添加到您的清单文件中。 根据 Google 文档 "A wake lock is a mechanism to indicate that your application needs to have the device stay on." 这是您必须在清单中添加的行:
<uses-permission android:name="android.permission.WAKE_LOCK" />
您需要在 BroadcastReceiver 的 onReceive() 方法中实现此对象。您可以按照本教程使用您需要的所有内容。 https://www.javacodegeeks.com/2012/09/android-alarmmanager-tutorial.html
此外,请注意,您将保留设备 "awake",因此您将保留影响电池寿命的 phone 处理,但即使锁屏了
希望对您有所帮助!
我使用服务
public class AlarmService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onStart(Intent intent, int startid) {
//This is my Code and set Alarm
stopSelf();
}
}