AlarmManager 仅在第一次触发,即使设置为重复

AlarmManager triggers only the first time even when set to repeating

我想弄清楚这个问题已经有一段时间了。
在我的 activity 中,我将警报管理器设置为每 2 分钟触发一次(用于测试)并通过接收器调用服务。该服务假设进行网络调用等。

我的问题是 AlarmManager 第一次正确触发但再也没有触发。我错过了什么?

在我的 activity 中,我这样做 -

        //Register an alarm manager
        //If no alarm is set
        Intent alarmIntent = new Intent(context, AlarmReceiver.class);
        alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);

        if(!defaultSharedPref.getBoolean("isAlarmSet",false)){
            AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
          manager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                    SystemClock.elapsedRealtime(),
                    R.string.interval,
                    pendingIntent);
            editor = defaultSharedPref.edit();
            editor.putBoolean("isAlarmSet",true);
            editor.commit();
        }

在我的清单中:-

<receiver android:process=":remote" android:name=".receiver.AlarmReceiver" />

<service android:name=".service.AlarmService"/>

我的收件人:-

public class AlarmReceiver extends WakefulBroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i = new Intent(context, AlarmService.class);
        startWakefulService(context,i);
    }
}

我什至尝试了 "setRepeating" 但没有成功。它仍然只触发一次。 有人可以指出我错过了什么吗?

提前致谢。

作为重复计时器的间隔,您将提供一个资源 ID - R.string.interval。这没有意义,但会编译,因为它是一个整数。如果你想把你的间隔作为资源,你最好使用整数资源,但你需要的最关键的改变是传递资源的实际 value 而不是资源id。因此,为此,请使用 Resources.getInteger 或 getString.

这应该可行,但我建议您根本不要使用字符串资源:

manager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 
    SystemClock.elapsedRealtime(),
    Integer.parseInt(getResources().getString(R.string.interval)), 
    pendingIntent);`

您在实践中没有看到任何触发警报的原因是资源 ID 是非常大的整数,通常在 0x8000000 范围内,因此您有效地设置了间隔非常长的周期性警报。如果再等一个月左右,就会触发警报。 :-)

如果你想要一种更灵活的方式来安排作业,我会推荐这个库,它为你抽象了所用的调度程序:https://github.com/evernote/android-job