SyncManager: add back support for contact groups

Groups are saved as separate vCards. We removed support for groups to
speed up development and deferred adding them back until there was
demand.

There is demand now, and also, not having this support resulted in the
sync not working, not just groups not supported.

Many thanks to "359" (this user's preferred alias) for investigating and
reporting this issue.
pull/14/head
Tom Hacohen 7 years ago
parent 5031efe845
commit c54baccdc7

@ -138,6 +138,7 @@ dependencies {
compile group: 'com.madgag.spongycastle', name: 'prov', version: '1.54.0.0'
compile group: 'com.google.code.gson', name: 'gson', version: '1.7.2'
compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'
compile 'org.apache.commons:commons-collections4:4.1'
provided 'org.projectlombok:lombok:1.16.16'
// for tests

@ -25,6 +25,7 @@ import com.etesync.syncadapter.App;
import org.apache.commons.lang3.ArrayUtils;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashSet;
@ -41,10 +42,13 @@ import at.bitfire.vcard4android.BatchOperation;
import at.bitfire.vcard4android.CachedGroupMembership;
import at.bitfire.vcard4android.Contact;
import at.bitfire.vcard4android.ContactsStorageException;
import ezvcard.VCardVersion;
import lombok.Cleanup;
import lombok.Getter;
import lombok.ToString;
import static at.bitfire.vcard4android.GroupMethod.GROUP_VCARDS;
@ToString(callSuper=true)
public class LocalGroup extends AndroidGroup implements LocalResource {
@Getter
@ -62,7 +66,15 @@ public class LocalGroup extends AndroidGroup implements LocalResource {
@Override
public String getContent() throws IOException, ContactsStorageException {
return null;
final Contact contact;
contact = getContact();
App.log.log(Level.FINE, "Preparing upload of VCard " + getUuid(), contact);
ByteArrayOutputStream os = new ByteArrayOutputStream();
contact.write(VCardVersion.V4_0, GROUP_VCARDS, os);
return os.toString();
}
@Override
@ -107,7 +119,7 @@ public class LocalGroup extends AndroidGroup implements LocalResource {
@Override
public void prepareForUpload() throws ContactsStorageException {
final String uid = UUID.randomUUID().toString();
final String newFileName = uid + ".vcf";
final String newFileName = uid;
ContentValues values = new ContentValues(2);
values.put(COLUMN_FILENAME, newFileName);

@ -10,7 +10,9 @@ package com.etesync.syncadapter.syncadapter;
import android.accounts.Account;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.SyncResult;
@ -33,14 +35,18 @@ import com.etesync.syncadapter.resource.LocalGroup;
import com.etesync.syncadapter.resource.LocalResource;
import org.apache.commons.codec.Charsets;
import org.apache.commons.collections4.SetUtils;
import org.apache.commons.io.IOUtils;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;
import java.util.logging.Level;
import at.bitfire.ical4android.CalendarStorageException;
import at.bitfire.vcard4android.BatchOperation;
import at.bitfire.vcard4android.Contact;
import at.bitfire.vcard4android.ContactsStorageException;
import lombok.Cleanup;
@ -100,6 +106,8 @@ public class ContactsSyncManager extends SyncManager {
journal = new JournalEntryManager(httpClient, remote, localAddressBook.getURL());
localAddressBook.includeGroups = true;
return true;
}
@ -109,12 +117,27 @@ public class ContactsSyncManager extends SyncManager {
LocalAddressBook addressBook = localAddressBook();
/* groups as separate VCards: thtere are group contacts and individual contacts */
/* groups as separate VCards: there are group contacts and individual contacts */
// mark groups with changed members as dirty
// FIXME: add back
BatchOperation batch = new BatchOperation(addressBook.provider);
for (LocalContact contact : addressBook.getDirtyContacts()) {
try {
App.log.fine("Looking for changed group memberships of contact " + contact.getFileName());
Set<Long> cachedGroups = contact.getCachedGroupMemberships(),
currentGroups = contact.getGroupMemberships();
for (Long groupID : SetUtils.disjunction(cachedGroups, currentGroups)) {
App.log.fine("Marking group as dirty: " + groupID);
batch.enqueue(new BatchOperation.Operation(
ContentProviderOperation.newUpdate(addressBook.syncAdapterURI(ContentUris.withAppendedId(ContactsContract.Groups.CONTENT_URI, groupID)))
.withValue(ContactsContract.Groups.DIRTY, 1)
.withYieldAllowed(true)
));
}
} catch (FileNotFoundException ignored) {
}
}
batch.commit();
}
@Override

Loading…
Cancel
Save