Use android-job to schedule refresh

pull/699/head
Alex Baker 8 years ago
parent ce89959c07
commit 70f64ee9e6

@ -412,18 +412,6 @@
android:permission="android.permission.BIND_JOB_SERVICE" android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false" /> android:exported="false" />
<receiver android:name=".jobs.MidnightRefreshJob$Broadcast" />
<service
android:name=".jobs.MidnightRefreshJob"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false" />
<receiver android:name=".jobs.RefreshJob$Broadcast" />
<service
android:name=".jobs.RefreshJob"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false" />
<receiver android:name=".location.GeofenceTransitionsIntentService$Broadcast" /> <receiver android:name=".location.GeofenceTransitionsIntentService$Broadcast" />
<service <service
android:name=".location.GeofenceTransitionsIntentService" android:name=".location.GeofenceTransitionsIntentService"

@ -2,8 +2,6 @@ package org.tasks.injection;
import dagger.Subcomponent; import dagger.Subcomponent;
import org.tasks.jobs.AfterSaveIntentService; import org.tasks.jobs.AfterSaveIntentService;
import org.tasks.jobs.MidnightRefreshJob;
import org.tasks.jobs.RefreshJob;
import org.tasks.locale.receiver.TaskerIntentService; import org.tasks.locale.receiver.TaskerIntentService;
import org.tasks.location.GeofenceTransitionsIntentService; import org.tasks.location.GeofenceTransitionsIntentService;
import org.tasks.scheduling.BackgroundScheduler; import org.tasks.scheduling.BackgroundScheduler;
@ -22,10 +20,6 @@ public interface IntentServiceComponent {
void inject(NotificationSchedulerIntentService notificationSchedulerIntentService); void inject(NotificationSchedulerIntentService notificationSchedulerIntentService);
void inject(MidnightRefreshJob midnightRefreshJob);
void inject(RefreshJob refreshJob);
void inject(BackgroundScheduler backgroundScheduler); void inject(BackgroundScheduler backgroundScheduler);
void inject(AfterSaveIntentService afterSaveIntentService); void inject(AfterSaveIntentService afterSaveIntentService);

@ -19,7 +19,6 @@ import timber.log.Timber;
public class BackupJob extends Job { public class BackupJob extends Job {
public static final String TAG = "job_backup";
static final String BACKUP_FILE_NAME_REGEX = "auto\\.[-\\d]+\\.json"; static final String BACKUP_FILE_NAME_REGEX = "auto\\.[-\\d]+\\.json";
static final FileFilter FILE_FILTER = f -> f.getName().matches(BACKUP_FILE_NAME_REGEX); static final FileFilter FILE_FILTER = f -> f.getName().matches(BACKUP_FILE_NAME_REGEX);
private static final Comparator<File> BY_LAST_MODIFIED = (f1, f2) -> private static final Comparator<File> BY_LAST_MODIFIED = (f1, f2) ->

@ -1,32 +0,0 @@
package org.tasks.jobs;
import android.content.Intent;
import android.support.annotation.NonNull;
import javax.inject.Inject;
import org.tasks.analytics.Tracker;
import org.tasks.injection.InjectingJobIntentService;
import timber.log.Timber;
public abstract class Job extends InjectingJobIntentService {
@Inject Tracker tracker;
@Override
protected void onHandleWork(@NonNull Intent intent) {
super.onHandleWork(intent);
Timber.d("onHandleIntent(%s)", intent);
try {
run();
} catch (Exception e) {
tracker.reportException(e);
} finally {
scheduleNext();
}
}
protected abstract void run();
protected abstract void scheduleNext();
}

@ -5,11 +5,13 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.evernote.android.job.Job; import com.evernote.android.job.Job;
import javax.inject.Inject; import javax.inject.Inject;
import org.tasks.LocalBroadcastManager;
import org.tasks.Notifier; import org.tasks.Notifier;
import org.tasks.backup.TasksJsonExporter; import org.tasks.backup.TasksJsonExporter;
import org.tasks.injection.ApplicationScope; import org.tasks.injection.ApplicationScope;
import org.tasks.injection.ForApplication; import org.tasks.injection.ForApplication;
import org.tasks.preferences.Preferences; import org.tasks.preferences.Preferences;
import org.tasks.scheduling.RefreshScheduler;
@ApplicationScope @ApplicationScope
public class JobCreator implements com.evernote.android.job.JobCreator { public class JobCreator implements com.evernote.android.job.JobCreator {
@ -19,25 +21,38 @@ public class JobCreator implements com.evernote.android.job.JobCreator {
private final Notifier notifier; private final Notifier notifier;
private final NotificationQueue notificationQueue; private final NotificationQueue notificationQueue;
private final TasksJsonExporter tasksJsonExporter; private final TasksJsonExporter tasksJsonExporter;
private final RefreshScheduler refreshScheduler;
private final LocalBroadcastManager localBroadcastManager;
static final String TAG_BACKUP = "tag_backup";
static final String TAG_REFRESH = "tag_refresh";
static final String TAG_MIDNIGHT_REFRESH = "tag_midnight_refresh";
static final String TAG_NOTIFICATION = "tag_notification";
@Inject @Inject
public JobCreator(@ForApplication Context context, Preferences preferences, Notifier notifier, public JobCreator(@ForApplication Context context, Preferences preferences, Notifier notifier,
NotificationQueue notificationQueue, TasksJsonExporter tasksJsonExporter) { NotificationQueue notificationQueue, TasksJsonExporter tasksJsonExporter,
RefreshScheduler refreshScheduler, LocalBroadcastManager localBroadcastManager) {
this.context = context; this.context = context;
this.preferences = preferences; this.preferences = preferences;
this.notifier = notifier; this.notifier = notifier;
this.notificationQueue = notificationQueue; this.notificationQueue = notificationQueue;
this.tasksJsonExporter = tasksJsonExporter; this.tasksJsonExporter = tasksJsonExporter;
this.refreshScheduler = refreshScheduler;
this.localBroadcastManager = localBroadcastManager;
} }
@Nullable @Nullable
@Override @Override
public Job create(@NonNull String tag) { public Job create(@NonNull String tag) {
switch (tag) { switch (tag) {
case NotificationJob.TAG: case TAG_NOTIFICATION:
return new NotificationJob(preferences, notifier, notificationQueue); return new NotificationJob(preferences, notifier, notificationQueue);
case BackupJob.TAG: case TAG_BACKUP:
return new BackupJob(context, tasksJsonExporter, preferences); return new BackupJob(context, tasksJsonExporter, preferences);
case TAG_MIDNIGHT_REFRESH:
case TAG_REFRESH:
return new RefreshJob(refreshScheduler, localBroadcastManager);
default: default:
throw new IllegalArgumentException("Unhandled tag: " + tag); throw new IllegalArgumentException("Unhandled tag: " + tag);
} }

@ -1,20 +1,14 @@
package org.tasks.jobs; package org.tasks.jobs;
import static org.tasks.time.DateTimeUtils.currentTimeMillis; import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import static org.tasks.time.DateTimeUtils.nextMidnight;
import static org.tasks.time.DateTimeUtils.printTimestamp; import static org.tasks.time.DateTimeUtils.printTimestamp;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import com.evernote.android.job.DailyJob; import com.evernote.android.job.DailyJob;
import com.evernote.android.job.JobRequest; import com.evernote.android.job.JobRequest;
import com.evernote.android.job.JobRequest.Builder; import com.evernote.android.job.JobRequest.Builder;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
import org.tasks.injection.ApplicationScope; import org.tasks.injection.ApplicationScope;
import org.tasks.injection.ForApplication;
import org.tasks.scheduling.AlarmManager;
import timber.log.Timber; import timber.log.Timber;
@ApplicationScope @ApplicationScope
@ -27,71 +21,49 @@ public class JobManager {
public static final int JOB_ID_NOTIFICATION_SCHEDULER = 9; public static final int JOB_ID_NOTIFICATION_SCHEDULER = 9;
public static final int JOB_ID_CALENDAR_NOTIFICATION = 10; public static final int JOB_ID_CALENDAR_NOTIFICATION = 10;
public static final int JOB_ID_TASKER = 11; public static final int JOB_ID_TASKER = 11;
static final int JOB_ID_REFRESH = 1;
static final int JOB_ID_MIDNIGHT_REFRESH = 6;
private final Context context;
private final AlarmManager alarmManager;
private final com.evernote.android.job.JobManager jobManager; private final com.evernote.android.job.JobManager jobManager;
@Inject @Inject
public JobManager(@ForApplication Context context, AlarmManager alarmManager, public JobManager(com.evernote.android.job.JobManager jobManager) {
com.evernote.android.job.JobManager jobManager) {
this.context = context;
this.alarmManager = alarmManager;
this.jobManager = jobManager; this.jobManager = jobManager;
} }
public void scheduleNotification(long time) { public void scheduleNotification(long time) {
Timber.d("schedule notification: %s", printTimestamp(time)); Timber.d("schedule notification: %s", printTimestamp(time));
new JobRequest.Builder(NotificationJob.TAG) new JobRequest.Builder(JobCreator.TAG_NOTIFICATION)
.setExact(calculateDelay(time)) .setExact(calculateDelay(time))
.build() .build()
.schedule(); .schedule();
} }
public void scheduleRefresh(long time) { public void scheduleRefresh(long time) {
Timber.d("%s: %s", RefreshJob.TAG, printTimestamp(time)); Timber.d("schedule refresh: %s", printTimestamp(time));
alarmManager.noWakeup(adjust(time), getPendingBroadcast(RefreshJob.Broadcast.class)); new JobRequest.Builder(JobCreator.TAG_REFRESH)
.setExact(calculateDelay(time))
.build()
.schedule();
} }
public void scheduleMidnightRefresh() { public void scheduleMidnightRefresh() {
long time = nextMidnight(); DailyJob.schedule(new Builder(JobCreator.TAG_MIDNIGHT_REFRESH), 0, 0);
Timber.d("%s: %s", MidnightRefreshJob.TAG, printTimestamp(time));
alarmManager.noWakeup(adjust(time), getPendingBroadcast(MidnightRefreshJob.Broadcast.class));
} }
public void scheduleBackup() { public void scheduleBackup() {
DailyJob.schedule(new Builder(BackupJob.TAG), 0, TimeUnit.HOURS.toMillis(24) - 1); DailyJob.schedule(new Builder(JobCreator.TAG_BACKUP), 0, TimeUnit.HOURS.toMillis(24) - 1);
} }
public void cancelNotifications() { public void cancelNotifications() {
Timber.d("cancelNotifications"); Timber.d("cancelNotifications");
jobManager.cancelAllForTag(NotificationJob.TAG); jobManager.cancelAllForTag(JobCreator.TAG_NOTIFICATION);
} }
public void cancelRefresh() { public void cancelRefresh() {
Timber.d("cancelRefresh"); Timber.d("cancelRefresh");
alarmManager.cancel(getPendingIntent(RefreshJob.TAG)); jobManager.cancelAllForTag(JobCreator.TAG_REFRESH);
} }
private long calculateDelay(long time) { private long calculateDelay(long time) {
return Math.max(5000, time - currentTimeMillis()); return Math.max(5000, time - currentTimeMillis());
} }
private long adjust(long time) {
return Math.max(time, currentTimeMillis() + 5000);
}
private PendingIntent getPendingIntent(String tag) {
switch (tag) {
case RefreshJob.TAG:
return getPendingBroadcast(RefreshJob.Broadcast.class);
default:
throw new RuntimeException("Unexpected tag: " + tag);
}
}
private <T> PendingIntent getPendingBroadcast(Class<T> c) {
return PendingIntent.getBroadcast(context, 0, new Intent(context, c), 0);
}
} }

@ -1,5 +0,0 @@
package org.tasks.jobs;
public abstract class MidnightJob extends Job {
}

@ -1,41 +0,0 @@
package org.tasks.jobs;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.JobIntentService;
import javax.inject.Inject;
import org.tasks.LocalBroadcastManager;
import org.tasks.injection.IntentServiceComponent;
public class MidnightRefreshJob extends MidnightJob {
public static final String TAG = "job_midnight_refresh";
@Inject LocalBroadcastManager localBroadcastManager;
@Inject JobManager jobManager;
@Override
protected void run() {
localBroadcastManager.broadcastRefresh();
}
@Override
protected void scheduleNext() {
jobManager.scheduleMidnightRefresh();
}
@Override
protected void inject(IntentServiceComponent component) {
component.inject(this);
}
public static class Broadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
JobIntentService
.enqueueWork(context, MidnightRefreshJob.class, JobManager.JOB_ID_MIDNIGHT_REFRESH,
intent);
}
}
}

@ -8,8 +8,6 @@ import org.tasks.preferences.Preferences;
public class NotificationJob extends com.evernote.android.job.Job { public class NotificationJob extends com.evernote.android.job.Job {
public static final String TAG = "job_notification";
private final Preferences preferences; private final Preferences preferences;
private final Notifier notifier; private final Notifier notifier;
private final NotificationQueue notificationQueue; private final NotificationQueue notificationQueue;

@ -1,40 +1,27 @@
package org.tasks.jobs; package org.tasks.jobs;
import android.content.BroadcastReceiver; import android.support.annotation.NonNull;
import android.content.Context; import com.evernote.android.job.Job;
import android.content.Intent;
import android.support.v4.app.JobIntentService;
import javax.inject.Inject;
import org.tasks.LocalBroadcastManager; import org.tasks.LocalBroadcastManager;
import org.tasks.injection.IntentServiceComponent;
import org.tasks.scheduling.RefreshScheduler; import org.tasks.scheduling.RefreshScheduler;
public class RefreshJob extends Job { public class RefreshJob extends Job {
public static final String TAG = "job_refresh"; public static final String TAG = "job_refresh";
@Inject RefreshScheduler refreshScheduler;
@Inject LocalBroadcastManager localBroadcastManager;
@Override private final RefreshScheduler refreshScheduler;
protected void inject(IntentServiceComponent component) { private final LocalBroadcastManager localBroadcastManager;
component.inject(this);
}
@Override RefreshJob(RefreshScheduler refreshScheduler, LocalBroadcastManager localBroadcastManager) {
protected void run() { this.refreshScheduler = refreshScheduler;
localBroadcastManager.broadcastRefresh(); this.localBroadcastManager = localBroadcastManager;
} }
@NonNull
@Override @Override
protected void scheduleNext() { protected Result onRunJob(@NonNull Params params) {
localBroadcastManager.broadcastRefresh();
refreshScheduler.scheduleNext(); refreshScheduler.scheduleNext();
} return Result.SUCCESS;
public static class Broadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
JobIntentService.enqueueWork(context, RefreshJob.class, JobManager.JOB_ID_REFRESH, intent);
}
} }
} }

@ -33,13 +33,4 @@ public class AlarmManager {
alarmManager.set(android.app.AlarmManager.RTC_WAKEUP, time, pendingIntent); alarmManager.set(android.app.AlarmManager.RTC_WAKEUP, time, pendingIntent);
} }
} }
@SuppressLint("NewApi")
public void noWakeup(long time, PendingIntent pendingIntent) {
if (atLeastKitKat()) {
alarmManager.setExact(android.app.AlarmManager.RTC, time, pendingIntent);
} else {
alarmManager.set(android.app.AlarmManager.RTC, time, pendingIntent);
}
}
} }

Loading…
Cancel
Save