无论设置什么时间,AlarmManager 的 setRepeating() 都会在 1 分钟后重复(本例中为 5 秒,API 18+)
setRepeating() of AlarmManager repeats after 1 minute no matter what the time is set (5 seconds in this case, API 18+)
我已将重复时间设置为 5 秒。第一个吐司在 5 秒后出现,但下一个吐司会在 1 分钟后重复。
我也用 setRepeating() 尝试了代码,它仍然不起作用。
这是我的代码:
public void constructJob(){
Intent alertIntent = new Intent(this, AlarmManagerService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this, 0,
alertIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
GregorianCalendar.getInstance().getTimeInMillis(),
repeatTime(),
pendingIntent
);
}
public long repeatTime(){
return 5000;
}
AlarmManagerService.java
public class AlarmManagerService extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "5 seconds have passed",
Toast.LENGTH_SHORT).show();
}
试试这个代码:
Calendar cal = Calendar.getInstance();
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), 5000, pendingIntent);
试试下面的代码:
Long time = new GregorianCalendar().getTimeInMillis() + 3000;
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,time,5000, pendingIntent);
一旦您运行此代码,警报将在 3 秒后首次触发,此后每 5 秒触发一次。
也尝试使用 WakefulBroadcastReceiver
而不是 BroadcastReceiver
,因为看起来 phone 会在一段时间后进入打瞌睡模式(如果你在 android M ).确保包含 WAKE_LOCK
权限以正确使用它。
另外你必须记住,你的警报的第一次触发不会在请求的时间之前,但它可能不会在那个时间之后的几乎整个间隔内发生。此外,虽然重复警报的总周期将按照要求进行,但警报的任何两次连续触发之间的时间可能会有所不同。
另外
setInExactRepeating()
不保证触发时间的准确性。您可以在 API 19 之前使用 setRepeating()
,但从 API 19 (KITKAT) 开始,警报传送不准确:OS 将转移警报以最大程度地减少唤醒和电池使用。
您可以做的是,设置一个 non-repeating 警报,当警报触发时,您可以在 BroadcastReceiver
中再次重置警报 有新的 API 支持需要严格交付保证的应用程序;参见 setWindow(int, long, long, PendingIntent)
和 setExact(int, long, PendingIntent)
。 targetSdkVersion 早于 API 19 的应用程序将继续看到以前的行为,即所有警报都在请求时准确传递。
参考
setInexactRepeating() Official documentation
Whosebug answer
试试这个
Calendar cur_cal = new GregorianCalendar();
PendingIntent pintent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pintent);
alarm.setRepeating(AlarmManager.RTC, cur_cal.getTimeInMillis(), interval, pintent);
试试这个
public void constructJob(){
Intent alertIntent = new Intent(this, AlarmManagerService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this, 0,
alertIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
GregorianCalendar.getInstance().getTimeInMillis(),
1000*5,
pendingIntent);
}
我遇到了完全相同的问题。我花了几个小时调试这个,最后我发现如果重复时间设置为低于一分钟,它总是在一分钟的时间表上触发警报!?
我按照这个例子:
http://www.compiletimeerror.com/2015/02/how-to-make-alarm-repeat-in-android-code.html#.Vp5UrCorKM8
它显示警报在 8 秒后触发,但在我的情况下它不会。
然后我尝试将重复时间设置为几分钟并且效果很好。我也喜欢从接收器触发警报提供更准确的重复时间(一个接收器用于启动警报管理器,它由自定义意图过滤器调用)
文档需要更新。我认为Android 5.1 (API version 22) 重复闹钟的最小周期为1分钟,并且以后不能设置少于5秒的闹钟。
如果您需要在一分钟内完成工作,只需直接设置闹钟,然后从该闹钟的处理程序中设置下一个,依此类推
如果您需要在 5 秒内完成工作,post 将它交给 Handler 而不是使用警报管理器?
不要使用setRepeating() 或setInExactRepeating,它不会在整整5 秒后重复。相反,尝试安排一次警报,然后在 onReceive() 方法中再次重新安排它,就像这样。这将在特定时间间隔后重复(在本例中为 5 秒)
MainActivity.java
public class MainActivity extends AppCompatActivity {
Button btnStartAlarm, btnStopAlarm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnStartAlarm = (Button) findViewById(R.id.btnStartAlarm);
btnStopAlarm = (Button) findViewById(R.id.btnStopAlarm);
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, intent, 0);
final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
btnStartAlarm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, pendingIntent);
}
});
btnStopAlarm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
alarmManager.cancel(pendingIntent);
}
});
}
}
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
public AlarmReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
Log.d("Javed", "onReceive called");
Toast.makeText(context, "onReceive called", Toast.LENGTH_LONG).show();
Intent intent1 = new Intent(context, AlarmReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 100, intent1, 0);
final AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, pendingIntent);
}
}
我已将重复时间设置为 5 秒。第一个吐司在 5 秒后出现,但下一个吐司会在 1 分钟后重复。
我也用 setRepeating() 尝试了代码,它仍然不起作用。
这是我的代码:
public void constructJob(){
Intent alertIntent = new Intent(this, AlarmManagerService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this, 0,
alertIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
GregorianCalendar.getInstance().getTimeInMillis(),
repeatTime(),
pendingIntent
);
}
public long repeatTime(){
return 5000;
}
AlarmManagerService.java
public class AlarmManagerService extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "5 seconds have passed",
Toast.LENGTH_SHORT).show();
}
试试这个代码:Calendar cal = Calendar.getInstance();
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), 5000, pendingIntent);
试试下面的代码:
Long time = new GregorianCalendar().getTimeInMillis() + 3000;
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,time,5000, pendingIntent);
一旦您运行此代码,警报将在 3 秒后首次触发,此后每 5 秒触发一次。
也尝试使用 WakefulBroadcastReceiver
而不是 BroadcastReceiver
,因为看起来 phone 会在一段时间后进入打瞌睡模式(如果你在 android M ).确保包含 WAKE_LOCK
权限以正确使用它。
另外你必须记住,你的警报的第一次触发不会在请求的时间之前,但它可能不会在那个时间之后的几乎整个间隔内发生。此外,虽然重复警报的总周期将按照要求进行,但警报的任何两次连续触发之间的时间可能会有所不同。
另外
setInExactRepeating()
不保证触发时间的准确性。您可以在 API 19 之前使用 setRepeating()
,但从 API 19 (KITKAT) 开始,警报传送不准确:OS 将转移警报以最大程度地减少唤醒和电池使用。
您可以做的是,设置一个 non-repeating 警报,当警报触发时,您可以在 BroadcastReceiver
中再次重置警报 有新的 API 支持需要严格交付保证的应用程序;参见 setWindow(int, long, long, PendingIntent)
和 setExact(int, long, PendingIntent)
。 targetSdkVersion 早于 API 19 的应用程序将继续看到以前的行为,即所有警报都在请求时准确传递。
参考
setInexactRepeating() Official documentation
Whosebug answer
试试这个
Calendar cur_cal = new GregorianCalendar();
PendingIntent pintent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pintent);
alarm.setRepeating(AlarmManager.RTC, cur_cal.getTimeInMillis(), interval, pintent);
试试这个
public void constructJob(){
Intent alertIntent = new Intent(this, AlarmManagerService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this, 0,
alertIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
GregorianCalendar.getInstance().getTimeInMillis(),
1000*5,
pendingIntent);
}
我遇到了完全相同的问题。我花了几个小时调试这个,最后我发现如果重复时间设置为低于一分钟,它总是在一分钟的时间表上触发警报!?
我按照这个例子: http://www.compiletimeerror.com/2015/02/how-to-make-alarm-repeat-in-android-code.html#.Vp5UrCorKM8
它显示警报在 8 秒后触发,但在我的情况下它不会。
然后我尝试将重复时间设置为几分钟并且效果很好。我也喜欢从接收器触发警报提供更准确的重复时间(一个接收器用于启动警报管理器,它由自定义意图过滤器调用)
文档需要更新。我认为Android 5.1 (API version 22) 重复闹钟的最小周期为1分钟,并且以后不能设置少于5秒的闹钟。
如果您需要在一分钟内完成工作,只需直接设置闹钟,然后从该闹钟的处理程序中设置下一个,依此类推
如果您需要在 5 秒内完成工作,post 将它交给 Handler 而不是使用警报管理器?
不要使用setRepeating() 或setInExactRepeating,它不会在整整5 秒后重复。相反,尝试安排一次警报,然后在 onReceive() 方法中再次重新安排它,就像这样。这将在特定时间间隔后重复(在本例中为 5 秒)
MainActivity.java
public class MainActivity extends AppCompatActivity {
Button btnStartAlarm, btnStopAlarm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnStartAlarm = (Button) findViewById(R.id.btnStartAlarm);
btnStopAlarm = (Button) findViewById(R.id.btnStopAlarm);
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, intent, 0);
final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
btnStartAlarm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, pendingIntent);
}
});
btnStopAlarm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
alarmManager.cancel(pendingIntent);
}
});
}
}
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
public AlarmReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
Log.d("Javed", "onReceive called");
Toast.makeText(context, "onReceive called", Toast.LENGTH_LONG).show();
Intent intent1 = new Intent(context, AlarmReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 100, intent1, 0);
final AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, pendingIntent);
}
}