Ответ 1
Примечание. Это сообщение было обновлено, чтобы включить API JobScheduler
в выпуске Android Lollipop. Следующее по-прежнему является жизнеспособным способом, но может считаться устаревшим, если вы нацеливаете 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
получает задание, чтобы повторять 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
отменить все аварийные сигналы такого типа.
- конечно, есть что-то делать в
Manifest
:
включают эти две строки
< receiver android:name=".AlarmReceiver"></receiver>
< service android:name=".YourService"></service>
внутри < application>
-tag. Без него система не принимает начало повторяющегося аварийного сигнала службы.
Начиная с версии 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);
или jobScheduler.cancelAll();
.