mirror of https://github.com/tasks/tasks
Working on background services
* Backup intent service runs at midnight - closes #109 * Broadcast refresh at midnight - closes #100 * Task list listens for refreshes - see #189 * Reschedule everything on app upgradepull/253/head
parent
24a9ac5d9c
commit
972b19fae0
@ -1,188 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.backup;
|
||||
|
||||
import com.todoroo.andlib.utility.AndroidUtilities;
|
||||
import com.todoroo.astrid.backup.BackupService.BackupDirectorySetting;
|
||||
import com.todoroo.astrid.dao.TaskDao;
|
||||
import com.todoroo.astrid.data.Task;
|
||||
import com.todoroo.astrid.test.DatabaseTestCase;
|
||||
|
||||
import org.tasks.R;
|
||||
import org.tasks.preferences.Preferences;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.tasks.date.DateTimeUtils.newDate;
|
||||
|
||||
public class BackupServiceTests extends DatabaseTestCase {
|
||||
|
||||
private static final long BACKUP_WAIT_TIME = 500L;
|
||||
|
||||
File temporaryDirectory = null;
|
||||
|
||||
@Inject TasksXmlExporter xmlExporter;
|
||||
@Inject TaskDao taskDao;
|
||||
@Inject Preferences preferences;
|
||||
|
||||
BackupDirectorySetting setting = new BackupDirectorySetting() {
|
||||
public File getBackupDirectory() {
|
||||
return temporaryDirectory;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void setUp() {
|
||||
super.setUp();
|
||||
|
||||
try {
|
||||
temporaryDirectory = File.createTempFile("backup", Long.toString(System.nanoTime()));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (!(temporaryDirectory.delete()))
|
||||
throw new RuntimeException("Could not delete temp file: " + temporaryDirectory.getAbsolutePath());
|
||||
if (!(temporaryDirectory.mkdir()))
|
||||
throw new RuntimeException("Could not create temp directory: " + temporaryDirectory.getAbsolutePath());
|
||||
|
||||
// make a temporary task
|
||||
Task task = new Task();
|
||||
task.setTitle("helicopter");
|
||||
taskDao.createNew(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() {
|
||||
super.tearDown();
|
||||
|
||||
if (temporaryDirectory != null) {
|
||||
for (File file : temporaryDirectory.listFiles())
|
||||
file.delete();
|
||||
temporaryDirectory.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean getBackupSetting() {
|
||||
return preferences.getBoolean(R.string.backup_BPr_auto_key, true);
|
||||
}
|
||||
|
||||
private void setBackupSetting(boolean setting) {
|
||||
preferences.setBoolean(R.string.backup_BPr_auto_key, setting);
|
||||
}
|
||||
|
||||
public void disabled_testBackup() {
|
||||
assertEquals(0, temporaryDirectory.list().length);
|
||||
|
||||
boolean backupSetting = getBackupSetting();
|
||||
try {
|
||||
setBackupSetting(true);
|
||||
preferences.setLong(BackupPreferences.PREF_BACKUP_LAST_DATE, 0);
|
||||
|
||||
// create a backup
|
||||
BackupService service = new BackupService();
|
||||
service.setBackupDirectorySetting(setting);
|
||||
service.testBackup(xmlExporter, preferences, getContext());
|
||||
|
||||
AndroidUtilities.sleepDeep(BACKUP_WAIT_TIME);
|
||||
|
||||
// assert file created
|
||||
File[] files = temporaryDirectory.listFiles();
|
||||
assertEquals(1, files.length);
|
||||
assertTrue(files[0].getName().matches(BackupService.BACKUP_FILE_NAME_REGEX));
|
||||
|
||||
// assert summary updated
|
||||
assertTrue(preferences.getLong(BackupPreferences.PREF_BACKUP_LAST_DATE, 0) > 0);
|
||||
assertNull(preferences.getStringValue(BackupPreferences.PREF_BACKUP_LAST_ERROR));
|
||||
} finally {
|
||||
setBackupSetting(backupSetting);
|
||||
}
|
||||
}
|
||||
|
||||
public void disabled_testNoBackup() {
|
||||
assertEquals(0, temporaryDirectory.list().length);
|
||||
System.err.println("test no backup");
|
||||
boolean backupSetting = getBackupSetting();
|
||||
try {
|
||||
setBackupSetting(false);
|
||||
preferences.setLong(BackupPreferences.PREF_BACKUP_LAST_DATE, 0);
|
||||
|
||||
// create a backup
|
||||
BackupService service = new BackupService();
|
||||
service.setBackupDirectorySetting(new BackupDirectorySetting() {
|
||||
public File getBackupDirectory() {
|
||||
fail("Why was this method called?");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
service.testBackup(xmlExporter, preferences, getContext());
|
||||
|
||||
AndroidUtilities.sleepDeep(BACKUP_WAIT_TIME);
|
||||
|
||||
// assert no file created
|
||||
File[] files = temporaryDirectory.listFiles();
|
||||
assertEquals(0, files.length);
|
||||
|
||||
// assert summary not updated
|
||||
assertEquals(0, preferences.getLong(BackupPreferences.PREF_BACKUP_LAST_DATE, 0));
|
||||
} finally {
|
||||
setBackupSetting(backupSetting);
|
||||
}
|
||||
}
|
||||
|
||||
public void testDeletion() throws IOException {
|
||||
// create a bunch of backups
|
||||
assertEquals(0, temporaryDirectory.list().length);
|
||||
|
||||
boolean backupSetting = getBackupSetting();
|
||||
try {
|
||||
setBackupSetting(true);
|
||||
|
||||
// create some user files
|
||||
File myFile = new File(temporaryDirectory, "beans");
|
||||
myFile.createNewFile();
|
||||
|
||||
// create some backup files
|
||||
for (int i = 0; i < 10; i++) {
|
||||
DateFormat df = new SimpleDateFormat("MMdd-HHmm");
|
||||
String name = String.format("auto.%02d%s.xml", i, df.format(newDate()));
|
||||
File tempFile = new File(temporaryDirectory, name);
|
||||
tempFile.createNewFile();
|
||||
}
|
||||
|
||||
// make one really old
|
||||
File[] files = temporaryDirectory.listFiles();
|
||||
files[4].setLastModified(System.currentTimeMillis() - 20000);
|
||||
|
||||
// assert files created
|
||||
assertEquals(11, files.length);
|
||||
|
||||
// backup
|
||||
BackupService service = new BackupService();
|
||||
service.setBackupDirectorySetting(setting);
|
||||
service.testBackup(xmlExporter, preferences, getContext());
|
||||
|
||||
AndroidUtilities.sleepDeep(BACKUP_WAIT_TIME);
|
||||
|
||||
// assert the oldest file was deleted
|
||||
assertTrue(temporaryDirectory.listFiles().length < 11);
|
||||
assertFalse(files[4].exists());
|
||||
|
||||
// assert user file still exists
|
||||
service.testBackup(xmlExporter, preferences, getContext());
|
||||
assertTrue(myFile.exists());
|
||||
|
||||
} finally {
|
||||
setBackupSetting(backupSetting);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package org.tasks.scheduling;
|
||||
|
||||
import com.todoroo.andlib.utility.AndroidUtilities;
|
||||
import com.todoroo.astrid.backup.BackupPreferences;
|
||||
import com.todoroo.astrid.backup.TasksXmlExporter;
|
||||
import com.todoroo.astrid.dao.TaskDao;
|
||||
import com.todoroo.astrid.data.Task;
|
||||
import com.todoroo.astrid.test.DatabaseTestCase;
|
||||
|
||||
import org.tasks.preferences.Preferences;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.tasks.date.DateTimeUtils.newDate;
|
||||
|
||||
public class BackupServiceTests extends DatabaseTestCase {
|
||||
|
||||
private static final long BACKUP_WAIT_TIME = 500L;
|
||||
|
||||
File temporaryDirectory = null;
|
||||
|
||||
@Inject TasksXmlExporter xmlExporter;
|
||||
@Inject TaskDao taskDao;
|
||||
@Inject Preferences preferences;
|
||||
|
||||
BackupIntentService.BackupDirectorySetting setting = new BackupIntentService.BackupDirectorySetting() {
|
||||
public File getBackupDirectory() {
|
||||
return temporaryDirectory;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void setUp() {
|
||||
super.setUp();
|
||||
|
||||
try {
|
||||
temporaryDirectory = File.createTempFile("backup", Long.toString(System.nanoTime()));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (!(temporaryDirectory.delete()))
|
||||
throw new RuntimeException("Could not delete temp file: " + temporaryDirectory.getAbsolutePath());
|
||||
if (!(temporaryDirectory.mkdir()))
|
||||
throw new RuntimeException("Could not create temp directory: " + temporaryDirectory.getAbsolutePath());
|
||||
|
||||
// make a temporary task
|
||||
Task task = new Task();
|
||||
task.setTitle("helicopter");
|
||||
taskDao.createNew(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() {
|
||||
super.tearDown();
|
||||
|
||||
if (temporaryDirectory != null) {
|
||||
for (File file : temporaryDirectory.listFiles())
|
||||
file.delete();
|
||||
temporaryDirectory.delete();
|
||||
}
|
||||
}
|
||||
|
||||
public void disabled_testBackup() {
|
||||
assertEquals(0, temporaryDirectory.list().length);
|
||||
|
||||
preferences.setLong(BackupPreferences.PREF_BACKUP_LAST_DATE, 0);
|
||||
|
||||
// create a backup
|
||||
BackupIntentService service = new BackupIntentService();
|
||||
service.setBackupDirectorySetting(setting);
|
||||
service.testBackup(xmlExporter, preferences, getContext());
|
||||
|
||||
AndroidUtilities.sleepDeep(BACKUP_WAIT_TIME);
|
||||
|
||||
// assert file created
|
||||
File[] files = temporaryDirectory.listFiles();
|
||||
assertEquals(1, files.length);
|
||||
assertTrue(files[0].getName().matches(BackupIntentService.BACKUP_FILE_NAME_REGEX));
|
||||
|
||||
// assert summary updated
|
||||
assertTrue(preferences.getLong(BackupPreferences.PREF_BACKUP_LAST_DATE, 0) > 0);
|
||||
}
|
||||
|
||||
public void testDeletion() throws IOException {
|
||||
// create a bunch of backups
|
||||
assertEquals(0, temporaryDirectory.list().length);
|
||||
|
||||
// create some user files
|
||||
File myFile = new File(temporaryDirectory, "beans");
|
||||
myFile.createNewFile();
|
||||
|
||||
// create some backup files
|
||||
for (int i = 0; i < 10; i++) {
|
||||
DateFormat df = new SimpleDateFormat("MMdd-HHmm");
|
||||
String name = String.format("auto.%02d%s.xml", i, df.format(newDate()));
|
||||
File tempFile = new File(temporaryDirectory, name);
|
||||
tempFile.createNewFile();
|
||||
}
|
||||
|
||||
// make one really old
|
||||
File[] files = temporaryDirectory.listFiles();
|
||||
files[4].setLastModified(System.currentTimeMillis() - 20000);
|
||||
|
||||
// assert files created
|
||||
assertEquals(11, files.length);
|
||||
|
||||
// backup
|
||||
BackupIntentService service = new BackupIntentService();
|
||||
service.setBackupDirectorySetting(setting);
|
||||
service.testBackup(xmlExporter, preferences, getContext());
|
||||
|
||||
AndroidUtilities.sleepDeep(BACKUP_WAIT_TIME);
|
||||
|
||||
// assert the oldest file was deleted
|
||||
assertTrue(temporaryDirectory.listFiles().length < 11);
|
||||
assertFalse(files[4].exists());
|
||||
|
||||
// assert user file still exists
|
||||
service.testBackup(xmlExporter, preferences, getContext());
|
||||
assertTrue(myFile.exists());
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.backup;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import com.todoroo.andlib.service.ContextManager;
|
||||
|
||||
import org.tasks.injection.InjectingBroadcastReceiver;
|
||||
import org.tasks.preferences.Preferences;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class BackupStartupReceiver extends InjectingBroadcastReceiver {
|
||||
|
||||
@Inject Preferences preferences;
|
||||
|
||||
@Override
|
||||
/** Called when device is restarted */
|
||||
public void onReceive(final Context context, Intent intent) {
|
||||
super.onReceive(context, intent);
|
||||
|
||||
ContextManager.setContext(context);
|
||||
BackupService.scheduleService(preferences, context);
|
||||
}
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.reminders;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.todoroo.andlib.service.ContextManager;
|
||||
import com.todoroo.andlib.utility.AndroidUtilities;
|
||||
import com.todoroo.astrid.alarms.AlarmService;
|
||||
import com.todoroo.astrid.dao.TaskDao;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tasks.injection.InjectingService;
|
||||
import org.tasks.scheduling.RefreshScheduler;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Schedules reminders in the background to prevent ANR's
|
||||
*
|
||||
* @author Tim Su
|
||||
*
|
||||
*/
|
||||
public class ReminderSchedulingService extends InjectingService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ReminderSchedulingService.class);
|
||||
|
||||
@Inject RefreshScheduler refreshScheduler;
|
||||
@Inject AlarmService alarmService;
|
||||
@Inject ReminderService reminderService;
|
||||
@Inject TaskDao taskDao;
|
||||
|
||||
/** Receive the alarm - start the synchronize service! */
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
ContextManager.setContext(ReminderSchedulingService.this);
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
delaySchedulingToPreventANRs();
|
||||
scheduleReminders();
|
||||
stopSelf();
|
||||
}
|
||||
}).start();
|
||||
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
|
||||
private void scheduleReminders() {
|
||||
try {
|
||||
reminderService.scheduleAllAlarms(taskDao);
|
||||
alarmService.scheduleAllAlarms();
|
||||
refreshScheduler.scheduleAllAlarms();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void delaySchedulingToPreventANRs() {
|
||||
AndroidUtilities.sleepDeep(5000L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.reminders;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import com.todoroo.andlib.service.ContextManager;
|
||||
|
||||
/**
|
||||
* Service which handles jobs that need to be run when phone boots
|
||||
*
|
||||
* @author Tim Su <tim@todoroo.com>
|
||||
*
|
||||
*/
|
||||
public class ReminderStartupReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
/** Called when the system is started up */
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
ContextManager.setContext(context);
|
||||
startReminderSchedulingService(context);
|
||||
}
|
||||
|
||||
public static void startReminderSchedulingService(Context context) {
|
||||
context.startService(new Intent(context, ReminderSchedulingService.class));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package org.tasks.injection;
|
||||
|
||||
import android.app.IntentService;
|
||||
import android.content.Intent;
|
||||
|
||||
public class InjectingIntentService extends IntentService {
|
||||
|
||||
public InjectingIntentService(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
((Injector) getApplication())
|
||||
.getObjectGraph()
|
||||
.plus(new IntentServiceModule())
|
||||
.inject(this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package org.tasks.injection;
|
||||
|
||||
import org.tasks.scheduling.*;
|
||||
|
||||
import dagger.Module;
|
||||
|
||||
@Module(addsTo = TasksModule.class,
|
||||
injects = {
|
||||
AlarmSchedulingIntentService.class,
|
||||
BackupIntentService.class,
|
||||
MidnightRefreshService.class,
|
||||
RefreshSchedulerIntentService.class,
|
||||
ReminderSchedulerIntentService.class
|
||||
})
|
||||
public class IntentServiceModule {
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package org.tasks.receivers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tasks.injection.InjectingBroadcastReceiver;
|
||||
import org.tasks.scheduling.BackgroundScheduler;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class BootCompletedReceiver extends InjectingBroadcastReceiver {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(BootCompletedReceiver.class);
|
||||
|
||||
@Inject BackgroundScheduler backgroundScheduler;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
super.onReceive(context, intent);
|
||||
|
||||
log.debug("onReceive(context, {})", intent);
|
||||
|
||||
backgroundScheduler.scheduleEverything();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package org.tasks.receivers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tasks.injection.InjectingBroadcastReceiver;
|
||||
import org.tasks.scheduling.BackgroundScheduler;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class FirstLaunchReceiver extends InjectingBroadcastReceiver {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FirstLaunchReceiver.class);
|
||||
|
||||
@Inject BackgroundScheduler backgroundScheduler;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
super.onReceive(context, intent);
|
||||
|
||||
log.debug("onReceive(context, {})", intent);
|
||||
|
||||
backgroundScheduler.scheduleBackupService();
|
||||
backgroundScheduler.scheduleMidnightRefresh();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package org.tasks.receivers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tasks.injection.InjectingBroadcastReceiver;
|
||||
import org.tasks.scheduling.BackgroundScheduler;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class MyPackageReplacedReceiver extends InjectingBroadcastReceiver {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MyPackageReplacedReceiver.class);
|
||||
|
||||
@Inject BackgroundScheduler backgroundScheduler;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
super.onReceive(context, intent);
|
||||
|
||||
log.debug("onReceive(context, {})", intent);
|
||||
|
||||
backgroundScheduler.scheduleEverything();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package org.tasks.receivers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tasks.injection.InjectingBroadcastReceiver;
|
||||
import org.tasks.scheduling.BackgroundScheduler;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class PackageReplacedReceiver extends InjectingBroadcastReceiver {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(PackageReplacedReceiver.class);
|
||||
|
||||
@Inject BackgroundScheduler backgroundScheduler;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
super.onReceive(context, intent);
|
||||
|
||||
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED) && context.getPackageName().equals(intent.getData().getSchemeSpecificPart())) {
|
||||
log.debug("onReceive(context, {})", intent);
|
||||
backgroundScheduler.scheduleEverything();
|
||||
} else {
|
||||
log.debug("ignoring {}", intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package org.tasks.scheduling;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import com.todoroo.astrid.alarms.AlarmService;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tasks.injection.InjectingIntentService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class AlarmSchedulingIntentService extends InjectingIntentService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AlarmSchedulingIntentService.class);
|
||||
|
||||
@Inject AlarmService alarmService;
|
||||
|
||||
public AlarmSchedulingIntentService() {
|
||||
super(AlarmSchedulingIntentService.class.getSimpleName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
super.onHandleIntent(intent);
|
||||
|
||||
log.debug("onHandleIntent({})", intent);
|
||||
|
||||
alarmService.scheduleAllAlarms();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package org.tasks.scheduling;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import org.tasks.injection.ForApplication;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class BackgroundScheduler {
|
||||
private Context context;
|
||||
|
||||
@Inject
|
||||
public BackgroundScheduler(@ForApplication Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void scheduleEverything() {
|
||||
context.startService(new Intent(context, RefreshSchedulerIntentService.class));
|
||||
context.startService(new Intent(context, AlarmSchedulingIntentService.class));
|
||||
context.startService(new Intent(context, ReminderSchedulerIntentService.class));
|
||||
scheduleBackupService();
|
||||
scheduleMidnightRefresh();
|
||||
}
|
||||
|
||||
public void scheduleBackupService() {
|
||||
context.startService(new Intent(context, BackupIntentService.class));
|
||||
}
|
||||
|
||||
public void scheduleMidnightRefresh() {
|
||||
context.startService(new Intent(context, MidnightRefreshService.class));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
package org.tasks.scheduling;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tasks.injection.InjectingIntentService;
|
||||
import org.tasks.preferences.Preferences;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.tasks.date.DateTimeUtils.currentTimeMillis;
|
||||
import static org.tasks.date.DateTimeUtils.newDateTime;
|
||||
|
||||
public abstract class MidnightIntentService extends InjectingIntentService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MidnightIntentService.class);
|
||||
|
||||
private static final long PADDING = SECONDS.toMillis(1);
|
||||
|
||||
@Inject Preferences preferences;
|
||||
|
||||
public MidnightIntentService(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
super.onHandleIntent(intent);
|
||||
|
||||
long lastRun = preferences.getLong(getLastRunPreference(), 0);
|
||||
long nextRun = nextMidnight(lastRun);
|
||||
long now = currentTimeMillis();
|
||||
|
||||
if (nextRun <= now) {
|
||||
nextRun = nextMidnight(now);
|
||||
log.debug("running now [nextRun={}]", newDateTime(nextRun));
|
||||
preferences.setLong(getLastRunPreference(), now);
|
||||
run();
|
||||
} else {
|
||||
log.debug("will run at {} [lastRun={}]", newDateTime(nextRun), newDateTime(lastRun));
|
||||
}
|
||||
|
||||
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||
PendingIntent pendingIntent = PendingIntent.getService(this, 0, new Intent(this, this.getClass()), PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
alarmManager.set(AlarmManager.RTC, nextRun + PADDING, pendingIntent);
|
||||
}
|
||||
|
||||
private static long nextMidnight(long timestamp) {
|
||||
return newDateTime(timestamp).withMillisOfDay(0).plusDays(1).getMillis();
|
||||
}
|
||||
|
||||
abstract void run();
|
||||
|
||||
abstract String getLastRunPreference();
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package org.tasks.scheduling;
|
||||
|
||||
import org.tasks.Broadcaster;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class MidnightRefreshService extends MidnightIntentService {
|
||||
|
||||
@Inject Broadcaster broadcaster;
|
||||
|
||||
public MidnightRefreshService() {
|
||||
super(MidnightRefreshService.class.getSimpleName());
|
||||
}
|
||||
|
||||
@Override
|
||||
void run() {
|
||||
broadcaster.refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
String getLastRunPreference() {
|
||||
return "midnightRefreshDate";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package org.tasks.scheduling;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tasks.injection.InjectingIntentService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class RefreshSchedulerIntentService extends InjectingIntentService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RefreshSchedulerIntentService.class);
|
||||
|
||||
@Inject RefreshScheduler refreshScheduler;
|
||||
|
||||
public RefreshSchedulerIntentService() {
|
||||
super(RefreshSchedulerIntentService.class.getSimpleName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
super.onHandleIntent(intent);
|
||||
|
||||
log.debug("onHandleIntent({})", intent);
|
||||
|
||||
refreshScheduler.scheduleApplicationRefreshes();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package org.tasks.scheduling;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import com.todoroo.astrid.dao.TaskDao;
|
||||
import com.todoroo.astrid.reminders.ReminderService;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tasks.injection.InjectingIntentService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class ReminderSchedulerIntentService extends InjectingIntentService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ReminderSchedulerIntentService.class);
|
||||
|
||||
@Inject ReminderService reminderService;
|
||||
@Inject TaskDao taskDao;
|
||||
|
||||
public ReminderSchedulerIntentService() {
|
||||
super(ReminderSchedulerIntentService.class.getSimpleName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
super.onHandleIntent(intent);
|
||||
|
||||
log.debug("onHandleIntent({})", intent);
|
||||
|
||||
reminderService.scheduleAllAlarms(taskDao);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="at_most_honeycomb">false</bool>
|
||||
<bool name="at_least_honeycomb_mr1">true</bool>
|
||||
</resources>
|
||||
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="at_most_honeycomb">true</bool>
|
||||
<bool name="at_least_honeycomb_mr1">false</bool>
|
||||
</resources>
|
||||
Loading…
Reference in New Issue