Use SyncAdapter to push new tasks

pull/437/head
Alex Baker 8 years ago
parent 3235d5e6df
commit c224103e81

@ -96,7 +96,7 @@ public class GtasksListServiceTest extends DatabaseTestCase {
assertEquals(
asList(newGtaskList(with(REMOTE_ID, "1"), with(LAST_SYNC, 0L))),
gtasksListService.getListsToUpdate(new TaskLists().setItems(asList(taskList))));
gtasksListService.getListsToUpdate(asList(taskList)));
}
private void setLists(TaskList... list) {

@ -6,7 +6,6 @@
package com.todoroo.astrid.gtasks;
import com.google.api.services.tasks.model.TaskList;
import com.google.api.services.tasks.model.TaskLists;
import com.todoroo.astrid.dao.StoreObjectDao;
import java.util.HashSet;
@ -80,9 +79,9 @@ public class GtasksListService {
}
}
public List<GtasksList> getListsToUpdate(TaskLists remoteLists) {
public List<GtasksList> getListsToUpdate(List<TaskList> remoteLists) {
List<GtasksList> listsToUpdate = newArrayList();
for (TaskList remoteList : remoteLists.getItems()) {
for (TaskList remoteList : remoteLists) {
GtasksList localList = getList(remoteList.getId());
String listName = localList.getName();
Long lastSync = localList.getLastSync();

@ -5,7 +5,6 @@
*/
package com.todoroo.astrid.gtasks.sync;
import android.content.ContentValues;
import android.text.TextUtils;
import com.todoroo.andlib.data.Callback;
@ -15,7 +14,6 @@ import com.todoroo.andlib.sql.Functions;
import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.dao.MetadataDao;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Metadata;
@ -24,15 +22,12 @@ import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gtasks.GtasksMetadata;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.OrderedMetadataListUpdater;
import com.todoroo.astrid.gtasks.api.GtasksApiUtilities;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import com.todoroo.astrid.gtasks.api.HttpNotFoundException;
import com.todoroo.astrid.gtasks.api.MoveRequest;
import org.tasks.gtasks.SyncAdapterHelper;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@ -46,12 +41,9 @@ import timber.log.Timber;
@Singleton
public class GtasksSyncService {
private static final String DEFAULT_LIST = "@default"; //$NON-NLS-1$
private final MetadataDao metadataDao;
private final TaskDao taskDao;
private final GtasksPreferenceService gtasksPreferenceService;
private final GtasksMetadata gtasksMetadataFactory;
private final GtasksInvoker gtasksInvoker;
private final LinkedBlockingQueue<SyncOnSaveOperation> operationQueue = new LinkedBlockingQueue<>();
private final SyncAdapterHelper syncAdapterHelper;
@ -59,12 +51,11 @@ public class GtasksSyncService {
@Inject
public GtasksSyncService(MetadataDao metadataDao, TaskDao taskDao,
GtasksPreferenceService gtasksPreferenceService,
GtasksMetadata gtasksMetadataFactory, GtasksInvoker gtasksInvoker,
GtasksInvoker gtasksInvoker,
SyncAdapterHelper syncAdapterHelper) {
this.metadataDao = metadataDao;
this.taskDao = taskDao;
this.gtasksPreferenceService = gtasksPreferenceService;
this.gtasksMetadataFactory = gtasksMetadataFactory;
this.gtasksInvoker = gtasksInvoker;
this.syncAdapterHelper = syncAdapterHelper;
new OperationPushThread(operationQueue).start();
@ -100,10 +91,6 @@ public class GtasksSyncService {
}
}
public void enqueue(SyncOnSaveOperation operation) {
operationQueue.offer(operation);
}
private class OperationPushThread extends Thread {
private final LinkedBlockingQueue<SyncOnSaveOperation> queue;
@ -156,111 +143,6 @@ public class GtasksSyncService {
operationQueue.offer(new MoveOp(metadata));
}
/**
* Synchronize with server when data changes
*/
public void pushTaskOnSave(Task task, ContentValues values, GtasksInvoker invoker) throws IOException {
for (Metadata deleted : getDeleted(task.getId())) {
gtasksInvoker.deleteGtask(deleted.getValue(GtasksMetadata.LIST_ID), deleted.getValue(GtasksMetadata.ID));
metadataDao.delete(deleted.getId());
}
Metadata gtasksMetadata = metadataDao.getFirstActiveByTaskAndKey(task.getId(), GtasksMetadata.METADATA_KEY);
com.google.api.services.tasks.model.Task remoteModel;
boolean newlyCreated = false;
String remoteId;
String listId = gtasksPreferenceService.getDefaultList();
if (listId == null) {
com.google.api.services.tasks.model.TaskList defaultList = invoker.getGtaskList(DEFAULT_LIST);
if (defaultList != null) {
listId = defaultList.getId();
gtasksPreferenceService.setDefaultList(listId);
} else {
listId = DEFAULT_LIST;
}
}
if (gtasksMetadata == null || !gtasksMetadata.containsNonNullValue(GtasksMetadata.ID) ||
TextUtils.isEmpty(gtasksMetadata.getValue(GtasksMetadata.ID))) { //Create case
if (gtasksMetadata == null) {
gtasksMetadata = gtasksMetadataFactory.createEmptyMetadata(task.getId());
}
if (gtasksMetadata.containsNonNullValue(GtasksMetadata.LIST_ID)) {
listId = gtasksMetadata.getValue(GtasksMetadata.LIST_ID);
}
remoteModel = new com.google.api.services.tasks.model.Task();
newlyCreated = true;
} else { //update case
remoteId = gtasksMetadata.getValue(GtasksMetadata.ID);
listId = gtasksMetadata.getValue(GtasksMetadata.LIST_ID);
remoteModel = new com.google.api.services.tasks.model.Task();
remoteModel.setId(remoteId);
}
//If task was newly created but without a title, don't sync--we're in the middle of
//creating a task which may end up being cancelled. Also don't sync new but already
//deleted tasks
if (newlyCreated &&
(!values.containsKey(Task.TITLE.name) || TextUtils.isEmpty(task.getTitle()) || task.getDeletionDate() > 0)) {
return;
}
//Update the remote model's changed properties
if (values.containsKey(Task.DELETION_DATE.name) && task.isDeleted()) {
remoteModel.setDeleted(true);
}
if (values.containsKey(Task.TITLE.name)) {
remoteModel.setTitle(task.getTitle());
}
if (values.containsKey(Task.NOTES.name)) {
remoteModel.setNotes(task.getNotes());
}
if (values.containsKey(Task.DUE_DATE.name) && task.hasDueDate()) {
remoteModel.setDue(GtasksApiUtilities.unixTimeToGtasksDueDate(task.getDueDate()));
}
if (values.containsKey(Task.COMPLETION_DATE.name)) {
if (task.isCompleted()) {
remoteModel.setCompleted(GtasksApiUtilities.unixTimeToGtasksCompletionTime(task.getCompletionDate()));
remoteModel.setStatus("completed"); //$NON-NLS-1$
} else {
remoteModel.setCompleted(null);
remoteModel.setStatus("needsAction"); //$NON-NLS-1$
}
}
if (!newlyCreated) {
try {
invoker.updateGtask(listId, remoteModel);
} catch(HttpNotFoundException e) {
Timber.e("Received 404 response, deleting %s", gtasksMetadata);
metadataDao.delete(gtasksMetadata.getId());
return;
}
} else {
String parent = getRemoteParentId(gtasksMetadata);
String priorSibling = getRemoteSiblingId(listId, gtasksMetadata);
com.google.api.services.tasks.model.Task created = invoker.createGtask(listId, remoteModel, parent, priorSibling);
if (created != null) {
//Update the metadata for the newly created task
gtasksMetadata.setValue(GtasksMetadata.ID, created.getId());
gtasksMetadata.setValue(GtasksMetadata.LIST_ID, listId);
} else {
return;
}
}
task.setModificationDate(DateUtilities.now());
gtasksMetadata.setValue(GtasksMetadata.LAST_SYNC, DateUtilities.now() + 1000L);
metadataDao.persist(gtasksMetadata);
task.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true);
taskDao.saveExistingWithSqlConstraintCheck(task);
}
public void pushMetadataOnSave(Metadata model, GtasksInvoker invoker) throws IOException {
AndroidUtilities.sleepDeep(1000L);
@ -303,16 +185,10 @@ public class GtasksSyncService {
});
}
private List<Metadata> getDeleted(long taskId) {
return metadataDao.toList(Criterion.and(
MetadataDao.MetadataCriteria.byTaskAndwithKey(taskId, GtasksMetadata.METADATA_KEY),
MetadataDao.MetadataCriteria.isDeleted()));
}
/**
* Gets the remote id string of the parent task
*/
private String getRemoteParentId(Metadata gtasksMetadata) {
public String getRemoteParentId(Metadata gtasksMetadata) {
String parent = null;
if (gtasksMetadata.containsNonNullValue(GtasksMetadata.PARENT_TASK)) {
long parentId = gtasksMetadata.getValue(GtasksMetadata.PARENT_TASK);
@ -330,7 +206,7 @@ public class GtasksSyncService {
/**
* Gets the remote id string of the previous sibling task
*/
private String getRemoteSiblingId(String listId, Metadata gtasksMetadata) {
public String getRemoteSiblingId(String listId, Metadata gtasksMetadata) {
final AtomicInteger indentToMatch = new AtomicInteger(gtasksMetadata.getValue(GtasksMetadata.INDENT));
final AtomicLong parentToMatch = new AtomicLong(gtasksMetadata.getValue(GtasksMetadata.PARENT_TASK));
final AtomicReference<String> sibling = new AtomicReference<>();

@ -30,7 +30,6 @@ import com.google.api.services.tasks.model.TaskLists;
import com.google.api.services.tasks.model.Tasks;
import com.todoroo.andlib.data.AbstractModel;
import com.todoroo.andlib.data.Callback;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.Query;
@ -46,7 +45,9 @@ import com.todoroo.astrid.gtasks.GtasksListService;
import com.todoroo.astrid.gtasks.GtasksMetadata;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.GtasksTaskListUpdater;
import com.todoroo.astrid.gtasks.api.GtasksApiUtilities;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import com.todoroo.astrid.gtasks.api.HttpNotFoundException;
import com.todoroo.astrid.gtasks.sync.GtasksSyncService;
import com.todoroo.astrid.gtasks.sync.GtasksTaskContainer;
import com.todoroo.astrid.service.TaskService;
@ -82,6 +83,8 @@ import static org.tasks.date.DateTimeUtils.newDateTime;
*/
public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter {
private static final String DEFAULT_LIST = "@default"; //$NON-NLS-1$
@Inject GtasksPreferenceService gtasksPreferenceService;
@Inject Broadcaster broadcaster;
@Inject TaskService taskService;
@ -93,7 +96,7 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter
@Inject GtasksInvoker gtasksInvoker;
@Inject TaskDao taskDao;
@Inject MetadataDao metadataDao;
@Inject GtasksMetadata gtasksMetadataFactory;
public GoogleTaskSyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
@ -144,12 +147,13 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter
}
private void synchronize() {
TaskLists remoteLists = null;
pushLocalChanges();
List<TaskList> gtaskLists = new ArrayList<>();
try {
List<TaskList> gtaskLists = new ArrayList<>();
String nextPageToken = null;
do {
remoteLists = gtasksInvoker.allGtaskLists(nextPageToken);
TaskLists remoteLists = gtasksInvoker.allGtaskLists(nextPageToken);
if (remoteLists == null) {
break;
}
@ -167,63 +171,145 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter
Timber.e(e, e.getMessage());
}
if (remoteLists == null) {
for (final GtasksList list : gtasksListService.getListsToUpdate(gtaskLists)) {
fetchAndApplyRemoteChanges(list);
}
}
private void pushLocalChanges() {
List<Task> tasks = taskDao.toList(Query.select(Task.PROPERTIES)
.join(Join.left(Metadata.TABLE, Criterion.and(MetadataDao.MetadataCriteria.withKey(GtasksMetadata.METADATA_KEY), Task.ID.eq(Metadata.TASK))))
.where(Criterion.or(Task.MODIFICATION_DATE.gt(GtasksMetadata.LAST_SYNC), GtasksMetadata.ID.eq(""))));
for (Task task : tasks) {
try {
pushTask(task, task.getMergedValues(), gtasksInvoker);
} catch (IOException e) {
Timber.e(e, e.getMessage());
}
}
}
/**
* Synchronize with server when data changes
*/
private void pushTask(Task task, ContentValues values, GtasksInvoker invoker) throws IOException {
for (Metadata deleted : getDeleted(task.getId())) {
gtasksInvoker.deleteGtask(deleted.getValue(GtasksMetadata.LIST_ID), deleted.getValue(GtasksMetadata.ID));
metadataDao.delete(deleted.getId());
}
Metadata gtasksMetadata = metadataDao.getFirstActiveByTaskAndKey(task.getId(), GtasksMetadata.METADATA_KEY);
com.google.api.services.tasks.model.Task remoteModel;
boolean newlyCreated = false;
String remoteId;
String listId = gtasksPreferenceService.getDefaultList();
if (listId == null) {
com.google.api.services.tasks.model.TaskList defaultList = invoker.getGtaskList(DEFAULT_LIST);
if (defaultList != null) {
listId = defaultList.getId();
gtasksPreferenceService.setDefaultList(listId);
} else {
listId = DEFAULT_LIST;
}
}
if (gtasksMetadata == null || !gtasksMetadata.containsNonNullValue(GtasksMetadata.ID) ||
TextUtils.isEmpty(gtasksMetadata.getValue(GtasksMetadata.ID))) { //Create case
if (gtasksMetadata == null) {
gtasksMetadata = gtasksMetadataFactory.createEmptyMetadata(task.getId());
}
if (gtasksMetadata.containsNonNullValue(GtasksMetadata.LIST_ID)) {
listId = gtasksMetadata.getValue(GtasksMetadata.LIST_ID);
}
remoteModel = new com.google.api.services.tasks.model.Task();
newlyCreated = true;
} else { //update case
remoteId = gtasksMetadata.getValue(GtasksMetadata.ID);
listId = gtasksMetadata.getValue(GtasksMetadata.LIST_ID);
remoteModel = new com.google.api.services.tasks.model.Task();
remoteModel.setId(remoteId);
}
//If task was newly created but without a title, don't sync--we're in the middle of
//creating a task which may end up being cancelled. Also don't sync new but already
//deleted tasks
if (newlyCreated &&
(!values.containsKey(Task.TITLE.name) || TextUtils.isEmpty(task.getTitle()) || task.getDeletionDate() > 0)) {
return;
}
for (final GtasksList list : gtasksListService.getListsToUpdate(remoteLists)) {
synchronizeListHelper(list, gtasksInvoker);
//Update the remote model's changed properties
if (values.containsKey(Task.DELETION_DATE.name) && task.isDeleted()) {
remoteModel.setDeleted(true);
}
pushUpdated(gtasksInvoker);
}
if (values.containsKey(Task.TITLE.name)) {
remoteModel.setTitle(task.getTitle());
}
if (values.containsKey(Task.NOTES.name)) {
remoteModel.setNotes(task.getNotes());
}
if (values.containsKey(Task.DUE_DATE.name) && task.hasDueDate()) {
remoteModel.setDue(GtasksApiUtilities.unixTimeToGtasksDueDate(task.getDueDate()));
}
if (values.containsKey(Task.COMPLETION_DATE.name)) {
if (task.isCompleted()) {
remoteModel.setCompleted(GtasksApiUtilities.unixTimeToGtasksCompletionTime(task.getCompletionDate()));
remoteModel.setStatus("completed"); //$NON-NLS-1$
} else {
remoteModel.setCompleted(null);
remoteModel.setStatus("needsAction"); //$NON-NLS-1$
}
}
private synchronized void pushUpdated(GtasksInvoker invoker) {
TodorooCursor<Task> queued = taskService.query(Query.select(Task.PROPERTIES).
join(Join.left(Metadata.TABLE, Criterion.and(MetadataDao.MetadataCriteria.withKey(GtasksMetadata.METADATA_KEY), Task.ID.eq(Metadata.TASK)))).where(
Criterion.or(Task.MODIFICATION_DATE.gt(GtasksMetadata.LAST_SYNC), Metadata.KEY.isNull())));
pushTasks(queued, invoker);
}
if (!newlyCreated) {
try {
invoker.updateGtask(listId, remoteModel);
} catch(HttpNotFoundException e) {
Timber.e("Received 404 response, deleting %s", gtasksMetadata);
metadataDao.delete(gtasksMetadata.getId());
return;
}
} else {
String parent = gtasksSyncService.getRemoteParentId(gtasksMetadata);
String priorSibling = gtasksSyncService.getRemoteSiblingId(listId, gtasksMetadata);
private synchronized void pushTasks(TodorooCursor<Task> queued, GtasksInvoker invoker) {
try {
for (queued.moveToFirst(); !queued.isAfterLast(); queued.moveToNext()) {
Task task = new Task(queued);
try {
gtasksSyncService.pushTaskOnSave(task, task.getMergedValues(), invoker);
} catch (IOException e) {
Timber.e(e, e.getMessage());
}
com.google.api.services.tasks.model.Task created = invoker.createGtask(listId, remoteModel, parent, priorSibling);
if (created != null) {
//Update the metadata for the newly created task
gtasksMetadata.setValue(GtasksMetadata.ID, created.getId());
gtasksMetadata.setValue(GtasksMetadata.LIST_ID, listId);
} else {
return;
}
} finally {
queued.close();
}
task.setModificationDate(DateUtilities.now());
gtasksMetadata.setValue(GtasksMetadata.LAST_SYNC, DateUtilities.now() + 1000L);
metadataDao.persist(gtasksMetadata);
task.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true);
taskDao.saveExistingWithSqlConstraintCheck(task);
}
private List<Metadata> getDeleted(long taskId) {
return metadataDao.toList(Criterion.and(
MetadataDao.MetadataCriteria.byTaskAndwithKey(taskId, GtasksMetadata.METADATA_KEY),
MetadataDao.MetadataCriteria.isDeleted()));
}
private synchronized void synchronizeListHelper(GtasksList list, GtasksInvoker invoker) {
private synchronized void fetchAndApplyRemoteChanges(GtasksList list) {
String listId = list.getRemoteId();
long lastSyncDate = list.getLastSync();
/**
* Find tasks which have been associated with the list internally, but have not yet been
* pushed to Google Tasks (and so haven't yet got a valid ID).
*/
Criterion not_pushed_tasks = Criterion.and(
Metadata.KEY.eq(GtasksMetadata.METADATA_KEY),
GtasksMetadata.LIST_ID.eq(listId),
GtasksMetadata.ID.eq("")
);
TodorooCursor<Task> qs = taskService.query(Query.select(Task.PROPERTIES).
join(Join.left(Metadata.TABLE, Criterion.and(MetadataDao.MetadataCriteria.withKey(GtasksMetadata.METADATA_KEY), Task.ID.eq(Metadata.TASK)))).where(not_pushed_tasks)
);
pushTasks(qs, invoker);
boolean includeDeletedAndHidden = lastSyncDate != 0;
try {
List<com.google.api.services.tasks.model.Task> tasks = new ArrayList<>();
String nextPageToken = null;
do {
Tasks taskList = invoker.getAllGtasksFromListId(listId, includeDeletedAndHidden,
Tasks taskList = gtasksInvoker.getAllGtasksFromListId(listId, includeDeletedAndHidden,
includeDeletedAndHidden, lastSyncDate + 1000L, nextPageToken);
if (taskList == null) {
break;

@ -5,23 +5,14 @@ import android.content.Context;
import android.content.Intent;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.SyncFlags;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import com.todoroo.astrid.gtasks.sync.GtasksSyncService;
import com.todoroo.astrid.service.TaskService;
import org.tasks.gtasks.SyncAdapterHelper;
import org.tasks.injection.BroadcastComponent;
import org.tasks.injection.InjectingBroadcastReceiver;
import java.io.IOException;
import javax.inject.Inject;
public class GoogleTaskPushReceiver extends InjectingBroadcastReceiver {
@ -29,9 +20,6 @@ public class GoogleTaskPushReceiver extends InjectingBroadcastReceiver {
private static final Property<?>[] TASK_PROPERTIES = { Task.ID, Task.TITLE,
Task.NOTES, Task.DUE_DATE, Task.COMPLETION_DATE, Task.DELETION_DATE };
@Inject GtasksPreferenceService gtasksPreferenceService;
@Inject GtasksSyncService gtasksSyncService;
@Inject TaskDao taskDao;
@Inject SyncAdapterHelper syncAdapterHelper;
@Override
@ -50,12 +38,8 @@ public class GoogleTaskPushReceiver extends InjectingBroadcastReceiver {
if(model.checkTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC)) {
return;
}
if (gtasksPreferenceService.isOngoing() && !model.checkTransitory(TaskService.TRANS_REPEAT_COMPLETE)) { //Don't try and sync changes that occur during a normal sync
return;
}
if (checkValuesForProperties(setValues, TASK_PROPERTIES) || model.checkTransitory(SyncFlags.FORCE_SYNC)) {
Task toPush = taskDao.fetch(model.getId(), TASK_PROPERTIES);
gtasksSyncService.enqueue(new TaskPushOp(toPush));
syncAdapterHelper.requestSynchronization();
}
}
@ -64,23 +48,6 @@ public class GoogleTaskPushReceiver extends InjectingBroadcastReceiver {
component.inject(this);
}
private class TaskPushOp implements GtasksSyncService.SyncOnSaveOperation {
protected Task model;
protected long creationDate = DateUtilities.now();
public TaskPushOp(Task model) {
this.model = model;
}
@Override
public void op(GtasksInvoker invoker) throws IOException {
if(DateUtilities.now() - creationDate < 1000) {
AndroidUtilities.sleepDeep(1000 - (DateUtilities.now() - creationDate));
}
gtasksSyncService.pushTaskOnSave(model, model.getMergedValues(), invoker);
}
}
/**
* Checks to see if any of the values changed are among the properties we sync
* @return false if none of the properties we sync were changed, true otherwise

@ -505,15 +505,7 @@ public class TaskListFragment extends InjectingListFragment implements
return;
}
final Activity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
refresh();
}
});
}
refresh();
}
}

@ -7,7 +7,6 @@ package com.todoroo.astrid.gtasks;
import com.todoroo.andlib.utility.DateUtilities;
import org.tasks.R;
import org.tasks.preferences.Preferences;
import javax.inject.Inject;
@ -81,8 +80,4 @@ public class GtasksPreferenceService {
public void recordSyncStart() {
preferences.setBoolean(IDENTIFIER + PREF_ONGOING, true);
}
public int getSyncInterval() {
return preferences.getIntegerFromString(R.string.gtasks_GPr_interval_key, 0);
}
}

@ -105,7 +105,6 @@ public class RepeatTaskCompleteListener extends InjectingBroadcastReceiver {
task.setReminderSnooze(0L);
task.setCompletionDate(0L);
task.setDueDateAdjustingHideUntil(newDueDate);
task.putTransitory(TaskService.TRANS_REPEAT_COMPLETE, true);
gcalHelper.rescheduleRepeatingTask(task);
taskService.save(task);

@ -47,8 +47,6 @@ import timber.log.Timber;
@Singleton
public class TaskService {
public static final String TRANS_REPEAT_COMPLETE = "repeat-complete"; //$NON-NLS-1$
private final TagDataDao tagDataDao;
private final TaskDao taskDao;
private final Broadcaster broadcaster;

@ -54,6 +54,14 @@ public class SyncAdapterHelper {
return true;
}
public void requestSynchronization() {
Account account = getAccount();
if (account == null) {
return;
}
ContentResolver.requestSync(account, AUTHORITY, new Bundle());
}
public boolean isEnabled() {
return preferences.getBoolean(R.string.sync_gtasks, false) && getAccount() != null;
}

@ -2,5 +2,5 @@
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.google"
android:contentAuthority="org.tasks"
android:supportsUploading="true"
android:supportsUploading="false"
android:userVisible="false" />
Loading…
Cancel
Save