警报管理器未按时触发

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