Gustavo, parte de este gran staff, nos hizo el favor de escribir este enunciado ya que controla muy bien este tema.
Solución:
Desafortunadamente, no puede programar un trabajo en un momento específico a partir de ahora. Si tiene una implementación crítica en el tiempo, debe usar AlarmManager para configurar la alarma que puede activarse mientras está en Doze usando setAndAllowWhileIdle() o setExactAndAllowWhileIdle().
Puede programar un trabajo, con un retraso inicial de una sola vez o ejecutarlo periódicamente, utilizando el WorkManager
como sigue:
Crear clase de trabajador:
public class MyWorker extends Worker
@Override
public Worker.WorkerResult doWork()
// Do the work here
// Indicate success or failure with your return value:
return WorkerResult.SUCCESS;
// (Returning RETRY tells WorkManager to try this task again
// later; FAILURE says not to try again.)
Luego programe OneTimeWorkRequest
como sigue:
OneTimeWorkRequest mywork=
new OneTimeWorkRequest.Builder(MyWorker.class)
.setInitialDelay(, )// Use this when you want to add initial delay or schedule initial work to `OneTimeWorkRequest` e.g. setInitialDelay(2, TimeUnit.HOURS)
.build();
WorkManager.getInstance().enqueue(mywork);
Puede configurar restricciones adicionales de la siguiente manera:
// Create a Constraints that defines when the task should run
Constraints myConstraints = new Constraints.Builder()
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
// Many other constraints are available, see the
// Constraints.Builder reference
.build();
Luego cree una OneTimeWorkRequest que use esas restricciones
OneTimeWorkRequest mywork=
new OneTimeWorkRequest.Builder(MyWorker.class)
.setConstraints(myConstraints)
.build();
WorkManager.getInstance().enqueue(mywork);
PeriodicWorkRequest se puede crear de la siguiente manera:
PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(MyWorker.class, 12, TimeUnit.HOURS)
.build();
WorkManager.getInstance().enqueue(periodicWork);
Esto crea un PeriodicWorkRequest para ejecutarse periódicamente una vez cada 12 horas.
PeriodicWorkRequests ahora admite retrasos iniciales desde la versión 2.1.0-alpha02. Puede usar el método setInitialDelay en PeriodicWorkRequest.Builder para establecer un retraso inicial. Enlace aquí
Ejemplo de horario en todos los días a las 8:00 am. aquí estoy usando la biblioteca de tiempo joda para operaciones de tiempo.
final int SELF_REMINDER_HOUR = 8;
if (DateTime.now().getHourOfDay() < SELF_REMINDER_HOUR)
delay = new Duration(DateTime.now() , DateTime.now().withTimeAtStartOfDay().plusHours(SELF_REMINDER_HOUR)).getStandardMinutes();
else
delay = new Duration(DateTime.now() , DateTime.now().withTimeAtStartOfDay().plusDays(1).plusHours(SELF_REMINDER_HOUR)).getStandardMinutes();
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(
WorkerReminderPeriodic.class,
24,
TimeUnit.HOURS,
PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS,
TimeUnit.MILLISECONDS)
.setInitialDelay(delay, TimeUnit.MINUTES)
.addTag("send_reminder_periodic")
.build();
WorkManager.getInstance()
.enqueueUniquePeriodicWork("send_reminder_periodic", ExistingPeriodicWorkPolicy.REPLACE, workRequest);
Hasta ahora no es posible lograr tiempos exactos usando PeriodicWorkRequest
.
Una solución fea sería usar un OneTimeWorkRequest
y cuando dispare, ponga otro OneTimeWorkRequest
con un nuevo período calculado, y así sucesivamente.
Sección de Reseñas y Valoraciones
Si te animas, puedes dejar una sección acerca de qué te ha impresionado de esta crónica.