Android Work Manager: как ставить рабочие места один раз в месяц
После этого вопроса я посмотрел на Android Job Scheduling, и мне кажется, что Work Manager - это новейший инструмент, если я хочу что-то делать раз в месяц. Я создал класс Worker и активировал его с помощью этого фрагмента в своей деятельности:
PeriodicWorkRequest myWorkRequest =
new PeriodicWorkRequest.Builder(MonthlyWorker.class, 20, TimeUnit.MINUTES)
.build();
WorkManager.getInstance().enqueueUniquePeriodicWork("my fancy test",ExistingPeriodicWorkPolicy.KEEP, myWorkRequest);
Несмотря на то, что я успешно проверил 20-минутный период, есть проблема: нет доступных TimeUnits для месяцев, только дни. Выполнение работы каждые 30 дней не будет работать по очевидным причинам. И что же мне делать? Нужно ли использовать другой API? Спасибо.
Я мог бы сделать что-то вроде if (dayOfMonth==1) do Function
, но я думаю, что это подрывает цель планировщика.
2 ответа
Вы можете сами по минутам сделать:
Просто конвертируйте дни в минуты:
Здесь: 30 дней = 43200 минут = 1 месяц
PeriodicWorkRequest myWorkRequest =
new PeriodicWorkRequest.Builder(MonthlyWorker.class, 43200, TimeUnit.MINUTES)
.build();
WorkManager.getInstance().enqueueUniquePeriodicWork("my fancy test",ExistingPeriodicWorkPolicy.KEEP, myWorkRequest);
ОБНОВИТЬ:
В соответствии с моим требованием, я хотел выполнять задачу каждые 30 минут в период с 8:00 до 18:00.
С помощью этого работника я сделал для вас, как вам требуется 1-го числа каждого месяца в период с 12 до 2 часов утра:
public class TestWorker extends Worker {
private static final String DEFAULT_START_TIME = "00:01"; //12:01 am
private static final String DEFAULT_END_TIME = "03:00"; // 03:00 am
private static final String TAG = "TestWorker";
public TestWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
/**
* Its for time
*/
DateFormat dateFormat = new SimpleDateFormat("HH:mm", Locale.getDefault());
/**
* Get Current Calendar Instance
*/
Calendar c = Calendar.getInstance();
// Get current day of month
int day = c.get(Calendar.DAY_OF_MONTH);
/**
* Get current time and compare with our start and end date.
*/
Date date = c.getTime();
String formattedDate = dateFormat.format(date);
try {
Date currentDate = dateFormat.parse(formattedDate);
Date startDate = dateFormat.parse(DEFAULT_START_TIME);
Date endDate = dateFormat.parse(DEFAULT_END_TIME);
/**
* This condition will check that day is 1, and time interval in between give time.
*/
if (day == 1 && currentDate.after(startDate) && currentDate.before(endDate)) {
// Do your work here
}
} catch (ParseException ignored) {
}
return Result.success();
}
}
Вы можете начать эту тестовую работу с интервалом X часов, чтобы он проверял каждый X час (например, в вашем случае вы можете дать 2 часа, чтобы он проверял каждые два часа)
Я не знаю, повлияет ли это на производительность или нет, но я думаю, что другого решения нет.
Вы можете начать работать, как показано ниже:
PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(MyWorker.class, 2, TimeUnit.HOURS)
.addTag("MYWORK")
.build();
WorkManager.getInstance().enqueueUniquePeriodicWork("MYWORK", ExistingPeriodicWorkPolicy.REPLACE, periodicWork);
Надеюсь, это поможет.
Может быть, вы можете создать WorkManager и проверить, является ли сегодня первый день в месяце, например:
Calendar c = Calendar.getInstance();
c.add(Calendar.MONTH, 0);
c.set(Calendar.DAY_OF_MONTH, 1);
String monthfirst = format.format(c.getTime());
System.out.println("===============nowfirst:" + monthfirst);
Если это правда, вы можете сделать вам реальную работу.