警报管理器未按时触发
Alarm Manager doesn't trigger on time
我正在尝试创建一个应用程序,我需要每 1、5、10 分钟等发送一次位置更新。
当应用程序处于 运行 时,它可以正常工作,但是当它进入 background/sleep 模式时,它不会正常工作 '工作准确。
我尝试了两种方法 setRepeating/setInExactRepeating
,但其中 none 在后台模式下工作。
public static void startSensorAlaram(Context ctx, long minutes) {
AlarmManager alarmManager = (AlarmManager) ctx
.getSystemService(Context.ALARM_SERVICE);
// Alarm_Receiver is a broadcast receiver.
Intent intent = new Intent(ctx, Alaram_Receiver.class);
intent.setAction(Utility.SENSOR_ACTION);
PendingIntent pi = PendingIntent.getBroadcast(ctx, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),minutes,pi);
// alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), minutes, pi);
}
public static void stopAlaramSensor(Context ctx) {
Intent intent = new Intent(ctx, Alaram_Receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 1,
intent, 0);
AlarmManager alarmManager = (AlarmManager) ctx
.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}
Alarm Receiver - Broadcast receiver
public class Alaram_Receiver extends WakefulBroadcastReceiver {
private SharedPreferences sp;
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
sp = context.getSharedPreferences(Utility.SHARED_PREFS, 0);
if (intent.getAction().equalsIgnoreCase(Utility.SENSOR_ACTION)) {
if (sp.getBoolean("logged_in", false)) {
// context.startService(new Intent(context,SensorService.class));
startWakefulService(context,new Intent(context,SensorService.class));
} else
Utility.stopAlaramSensor(context);
}
}
}
Note:-
最低API版本为15编译版本为23.
有两个问题。
1) 从 Android API >= 19 开始,您应该使用新的 AlarmManager.setExact()
方法而不是 set()
或 setRepeating()
。这里引用官方文档
Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will
shift alarms in order to minimize wakeups and battery use. There are
new APIs to support applications which need strict delivery
guarantees; see setWindow(int, long, long, PendingIntent) and
setExact(int, long, PendingIntent).
2) 从 Android 6.0 开始,引入了深度睡眠模式,称为 Doze
。
它旨在减少设备待机时的电池消耗。限制太多了,你在那种模式下能做的事情非常有限。您需要使用新的 AlarmManager.setExactAndAllowWhileIdle()
让闹钟在您喜欢的时间以打盹模式触发。
有关打瞌睡模式的更多信息,请参见此处 Optimizing for Doze and App Standby
我正在尝试创建一个应用程序,我需要每 1、5、10 分钟等发送一次位置更新。
当应用程序处于 运行 时,它可以正常工作,但是当它进入 background/sleep 模式时,它不会正常工作 '工作准确。
我尝试了两种方法 setRepeating/setInExactRepeating
,但其中 none 在后台模式下工作。
public static void startSensorAlaram(Context ctx, long minutes) {
AlarmManager alarmManager = (AlarmManager) ctx
.getSystemService(Context.ALARM_SERVICE);
// Alarm_Receiver is a broadcast receiver.
Intent intent = new Intent(ctx, Alaram_Receiver.class);
intent.setAction(Utility.SENSOR_ACTION);
PendingIntent pi = PendingIntent.getBroadcast(ctx, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),minutes,pi);
// alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), minutes, pi);
}
public static void stopAlaramSensor(Context ctx) {
Intent intent = new Intent(ctx, Alaram_Receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 1,
intent, 0);
AlarmManager alarmManager = (AlarmManager) ctx
.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}
Alarm Receiver - Broadcast receiver
public class Alaram_Receiver extends WakefulBroadcastReceiver {
private SharedPreferences sp;
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
sp = context.getSharedPreferences(Utility.SHARED_PREFS, 0);
if (intent.getAction().equalsIgnoreCase(Utility.SENSOR_ACTION)) {
if (sp.getBoolean("logged_in", false)) {
// context.startService(new Intent(context,SensorService.class));
startWakefulService(context,new Intent(context,SensorService.class));
} else
Utility.stopAlaramSensor(context);
}
}
}
Note:-
最低API版本为15编译版本为23.
有两个问题。
1) 从 Android API >= 19 开始,您应该使用新的 AlarmManager.setExact()
方法而不是 set()
或 setRepeating()
。这里引用官方文档
Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent).
2) 从 Android 6.0 开始,引入了深度睡眠模式,称为 Doze
。
它旨在减少设备待机时的电池消耗。限制太多了,你在那种模式下能做的事情非常有限。您需要使用新的 AlarmManager.setExactAndAllowWhileIdle()
让闹钟在您喜欢的时间以打盹模式触发。
有关打瞌睡模式的更多信息,请参见此处 Optimizing for Doze and App Standby