Add group support via VCard CATEGORIES (closes #48)

pull/2/head
rfc2822 10 years ago
parent d712238700
commit 9a809c9761

@ -33,6 +33,7 @@ import ezvcard.parameter.TelephoneType;
import ezvcard.property.Address;
import ezvcard.property.Anniversary;
import ezvcard.property.Birthday;
import ezvcard.property.Categories;
import ezvcard.property.Email;
import ezvcard.property.FormattedName;
import ezvcard.property.Impp;
@ -97,6 +98,7 @@ public class Contact extends Resource {
@Getter private List<Email> emails = new LinkedList<Email>();
@Getter private List<Impp> impps = new LinkedList<Impp>();
@Getter private List<Address> addresses = new LinkedList<Address>();
@Getter private List<String> categories = new LinkedList<String>();
@Getter private List<String> URLs = new LinkedList<String>();
@ -244,6 +246,12 @@ public class Contact extends Resource {
addresses = vcard.getAddresses();
vcard.removeProperties(Address.class);
// CATEGORY
Categories categories = vcard.getCategories();
if (categories != null)
this.categories = categories.getValues();
vcard.removeProperties(Categories.class);
// URL
for (Url url : vcard.getUrls())
URLs.add(url.getValue());
@ -361,6 +369,10 @@ public class Contact extends Resource {
for (Address address : addresses)
vcard.addAddress(address);
// CATEGORY
if (!categories.isEmpty())
vcard.setCategories(categories.toArray(new String[0]));
// URL
for (String url : URLs)
vcard.addUrl(url);

@ -20,11 +20,16 @@ import java.util.Set;
import lombok.Cleanup;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import android.accounts.Account;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentProviderOperation.Builder;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.DatabaseUtils;
@ -32,6 +37,7 @@ import android.net.Uri;
import android.os.RemoteException;
import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
import android.provider.ContactsContract.CommonDataKinds.Im;
import android.provider.ContactsContract.CommonDataKinds.Nickname;
import android.provider.ContactsContract.CommonDataKinds.Note;
@ -43,13 +49,10 @@ import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Groups;
import android.provider.ContactsContract.RawContacts;
import android.util.Log;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import at.bitfire.davdroid.syncadapter.AccountSettings;
import ezvcard.parameter.AddressType;
import ezvcard.parameter.EmailType;
import ezvcard.parameter.ImppType;
@ -61,8 +64,6 @@ import ezvcard.property.DateOrTimeProperty;
import ezvcard.property.Impp;
import ezvcard.property.Telephone;
import at.bitfire.davdroid.syncadapter.AccountSettings;
public class LocalAddressBook extends LocalCollection<Contact> {
private final static String TAG = "davdroid.LocalAddressBook";
@ -142,6 +143,33 @@ public class LocalAddressBook extends LocalCollection<Contact> {
.build());
}
@Override
public void commit() throws LocalStorageException {
super.commit();
// update group details for groups we have just created
Uri groupsUri = syncAdapterURI(Groups.CONTENT_URI);
try {
// newly created groups don't have a TITLE
@Cleanup Cursor cursor = providerClient.query(groupsUri,
new String[] { Groups.SOURCE_ID },
Groups.TITLE + " IS NULL", null, null
);
while (cursor != null && cursor.moveToNext()) {
// found group, set TITLE to SOURCE_ID and other details
String sourceID = cursor.getString(0);
pendingOperations.add(ContentProviderOperation.newUpdate(groupsUri)
.withSelection(Groups.SOURCE_ID + "=?", new String[] { sourceID })
.withValue(Groups.TITLE, sourceID)
.withValue(Groups.GROUP_VISIBLE, 1)
.build());
super.commit();
}
} catch (RemoteException e) {
throw new LocalStorageException("Couldn't update group names", e);
}
}
/* methods for populating the data object from the content provider */
@ -168,6 +196,7 @@ public class LocalAddressBook extends LocalCollection<Contact> {
populateNickname(c);
populateNote(c);
populatePostalAddresses(c);
populateCategories(c);
populateURLs(c);
populateEvents(c);
populateSipAddress(c);
@ -462,6 +491,57 @@ public class LocalAddressBook extends LocalCollection<Contact> {
}
}
protected void populateCategories(Contact c) throws RemoteException {
@Cleanup Cursor cursorMemberships = providerClient.query(dataURI(),
new String[] { GroupMembership.GROUP_ROW_ID, GroupMembership.GROUP_SOURCE_ID },
GroupMembership.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
new String[] { String.valueOf(c.getLocalID()), GroupMembership.CONTENT_ITEM_TYPE }, null);
List<String> categories = c.getCategories();
while (cursorMemberships != null && cursorMemberships.moveToNext()) {
long rowID = cursorMemberships.getLong(0);
String sourceID = cursorMemberships.getString(1);
// either a row ID or a source ID must be available
String where, whereArg;
if (sourceID == null) {
where = Groups._ID + "=?";
whereArg = String.valueOf(rowID);
} else {
where = Groups.SOURCE_ID + "=?";
whereArg = sourceID;
}
where += " AND " + Groups.DELETED + "=0"; // ignore deleted groups
Log.d(TAG, "Populating group from " + where + " " + whereArg);
// fetch group
@Cleanup Cursor cursorGroups = providerClient.query(Groups.CONTENT_URI,
new String[] { Groups.TITLE },
where, new String[] { whereArg }, null
);
if (cursorGroups != null && cursorGroups.moveToNext()) {
String title = cursorGroups.getString(0);
if (sourceID == null) { // Group wasn't created by DAVdroid
// SOURCE_ID IS NULL <=> _ID IS NOT NULL
Log.d(TAG, "Setting SOURCE_ID of non-DAVdroid group to title: " + title);
ContentValues v = new ContentValues(1);
v.put(Groups.SOURCE_ID, title);
v.put(Groups.GROUP_IS_READ_ONLY, 0);
v.put(Groups.GROUP_VISIBLE, 1);
providerClient.update(syncAdapterURI(Groups.CONTENT_URI), v, Groups._ID + "=?", new String[] { String.valueOf(rowID) });
sourceID = title;
}
// add group to CATEGORIES
if (sourceID != null)
categories.add(sourceID);
} else
Log.d(TAG, "Group not found (maybe deleted)");
}
}
protected void populateURLs(Contact c) throws RemoteException {
@Cleanup Cursor cursor = providerClient.query(dataURI(), new String[] { Website.URL },
Website.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
@ -562,7 +642,8 @@ public class LocalAddressBook extends LocalCollection<Contact> {
for (Address address : contact.getAddresses())
queueOperation(buildAddress(newDataInsertBuilder(localID, backrefIdx), address));
// TODO group membership
for (String category : contact.getCategories())
queueOperation(buildGroupMembership(newDataInsertBuilder(localID, backrefIdx), category));
for (String url : contact.getURLs())
queueOperation(buildURL(newDataInsertBuilder(localID, backrefIdx), url));
@ -870,6 +951,12 @@ public class LocalAddressBook extends LocalCollection<Contact> {
builder = builder.withValue(StructuredPostal.LABEL, typeLabel);
return builder;
}
protected Builder buildGroupMembership(Builder builder, String group) {
return builder
.withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE)
.withValue(GroupMembership.GROUP_SOURCE_ID, group);
}
protected Builder buildURL(Builder builder, String url) {
return builder

Loading…
Cancel
Save