带有WakefulBroadcastReceiver的AlarmManager setExact有时不精确

时间:2014-07-13 16:32:39

标签: android alarmmanager

使用Android 19 +

与WakefulBroadcastReceiver结合使用的setExact有时不会按时触发(可能是几秒钟左右)。我的意思是它的大部分时间。可能49次中有50次是正确的。

我不确定它是否仅仅是因为系统当时很忙而无法处理工作量或什么

以下是我设置闹钟的方法:

  AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
  Intent intent = new Intent(AlarmReceiver.INTENT_FILTER);
  PendingIntent alarmIntent = PendingIntent.getBroadcast(context, MyApplication.ALARM_REQUEST_CODE, intent,  PendingIntent.FLAG_UPDATE_CURRENT);
  alarmMgr.setExact(AlarmManager.RTC_WAKEUP, timeToWakeUp, alarmIntent);

这是我的接收者代码:

public class AlarmReceiver extends WakefulBroadcastReceiver {

public static final String INTENT_FILTER = "myfilter";

@Override
public void onReceive(Context context, Intent intent) {
    Intent service = new Intent(context, MyWakefulService.class);
    startWakefulService(context, service);

}

}

在WakefulService中

public class MyWakefulService extends IntentService {

....

@Override
protected void onHandleIntent(Intent intent) {

....

2 个答案:

答案 0 :(得分:24)

对于棉花糖时代(?),我们需要一些丑陋的代码如下...... :( API中的“delayInMillis”参数应该超过15分钟。 如果没有,系统会忽略不到15分钟的分钟。

private void registerExactAlarm(PendingIntent sender, long delayInMillis) {
    final int SDK_INT = Build.VERSION.SDK_INT;
    AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
    long timeInMillis = (System.currentTimeMillis() + delayInMillis) / 1000 * 1000;     //> example

    if (SDK_INT < Build.VERSION_CODES.KITKAT) {
        am.set(AlarmManager.RTC_WAKEUP, timeInMillis, sender);
    }
    else if (Build.VERSION_CODES.KITKAT <= SDK_INT  && SDK_INT < Build.VERSION_CODES.M) {
        am.setExact(AlarmManager.RTC_WAKEUP, timeInMillis, sender);
    }
    else if (SDK_INT >= Build.VERSION_CODES.M) {
        am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeInMillis, sender);
    }
}

答案 1 :(得分:8)

在API 19中添加了此行为:

  

从API 19(KITKAT)开始,警报传递不准确:操作系统将移动警报以最小化唤醒和电池使用。有新的API支持需要严格交付保证的应用程序;见setWindow(int, long, long, PendingIntent)setExact(int, long, PendingIntent)。 targetSdkVersion早于API 19的应用程序将继续查看之前在请求时准确传递所有警报的行为。

来自AlarmManager

重要setExact()仍然不一定非精确,正如文档所述:

  

警报将尽可能地传递到请求的触发时间。