注意:这篇文章已经更新为包含JobScheduler
Android Lollipop 版本的 API。以下仍然是一种可行的方法,但如果您的目标是 Android Lollipop 及更高版本,则可能被视为已弃用。请参阅下半部分的JobScheduler
替代方案。
执行重复任务的一种方法是:
创建一个类AlarmReceiver
public class AlarmReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Intent myService = new Intent(context, YourService.class);
context.startService(myService);
}
}
为YourService
您服务 ;-)
如果您的任务需要唤醒锁,建议从WakefulBroadcastReceiver
. 在这种情况下,不要忘记WAKE_LOCK
在您的清单中添加权限!
要开始您的定期轮询,请在您的活动中执行此代码:
Intent myAlarm = new Intent(getApplicationContext(), AlarmReceiver.class);
//myAlarm.putExtra("project_id", project_id); //Put Extra if needed
PendingIntent recurringAlarm = PendingIntent.getBroadcast(getApplicationContext(), 0, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Calendar updateTime = Calendar.getInstance();
//updateTime.setWhatever(0); //set time to start first occurence of alarm
alarms.setInexactRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), AlarmManager.INTERVAL_DAY, recurringAlarm); //you can modify the interval of course
此代码设置一个alarm
和一个可取消的pendingIntent
。让工作每天alarmManager
重复(第三个参数),但不精确,因此 CPU 确实在间隔后大约唤醒但不完全(它让操作系统选择最佳时间,从而减少电池消耗)。第一次启动警报(以及服务)将是您选择的时间。recurringAlarm
updateTime
最后但并非最不重要的一点:这是消除重复警报的方法
Intent myAlarm = new Intent(getApplicationContext(), AlarmReceiver.class);
//myAlarm.putExtra("project_id",project_id); //put the SAME extras
PendingIntent recurringAlarm = PendingIntent.getBroadcast(getApplicationContext(), 0, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarms.cancel(recurringAlarm);
此代码创建您(可能)现有警报的副本,并告诉alarmManager
取消所有此类警报。
包括这两行
< receiver android:name=".AlarmReceiver"></receiver>
< service android:name=".YourService"></service>
-标签内< application>
。没有它,系统不接受服务的周期性警报的启动。
从Android Lollipop版本开始,有一种优雅地解决此任务的新方法。这也使得仅在满足某些条件(例如网络状态)时才执行操作变得更加容易。
// wrap your stuff in a componentName
ComponentName mServiceComponent = new ComponentName(context, MyJobService.class);
// set up conditions for the job
JobInfo task = JobInfo.Builder(mJobId, mServiceComponent)
.setPeriodic(mIntervalMillis)
.setRequiresCharging(true) // default is "false"
.setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED) // Parameter may be "ANY", "NONE" (=default) or "UNMETERED"
.build();
// inform the system of the job
JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(task);
您还可以提供截止日期setOverrideDeadline(maxExecutionDelayMillis)
。
要摆脱这样的任务,只需调用jobScheduler.cancel(mJobId);
or jobScheduler.cancelAll();
。