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
我想弄清楚这个问题已经有一段时间了。
在我的 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