mirror of
https://github.com/etesync/android
synced 2025-05-04 07:59:09 +00:00
support for structured addresses (closes #29); bug fixes
This commit is contained in:
parent
fb671a67a4
commit
603758fcbc
@ -37,6 +37,13 @@
|
|||||||
<Type type="other" />
|
<Type type="other" />
|
||||||
</DataKind>
|
</DataKind>
|
||||||
|
|
||||||
|
<DataKind kind="postal" needsStructured="true" >
|
||||||
|
<Type type="home" />
|
||||||
|
<Type type="work" />
|
||||||
|
<Type type="other" />
|
||||||
|
<Type type="custom" />
|
||||||
|
</DataKind>
|
||||||
|
|
||||||
<DataKind
|
<DataKind
|
||||||
kind="nickname"
|
kind="nickname"
|
||||||
maxOccurs="1" />
|
maxOccurs="1" />
|
||||||
|
@ -23,7 +23,6 @@ import lombok.ToString;
|
|||||||
import net.fortuna.ical4j.data.ParserException;
|
import net.fortuna.ical4j.data.ParserException;
|
||||||
import net.fortuna.ical4j.model.Date;
|
import net.fortuna.ical4j.model.Date;
|
||||||
import net.fortuna.ical4j.model.ValidationException;
|
import net.fortuna.ical4j.model.ValidationException;
|
||||||
import net.fortuna.ical4j.util.CompatibilityHints;
|
|
||||||
import net.fortuna.ical4j.vcard.GroupRegistry;
|
import net.fortuna.ical4j.vcard.GroupRegistry;
|
||||||
import net.fortuna.ical4j.vcard.ParameterFactoryRegistry;
|
import net.fortuna.ical4j.vcard.ParameterFactoryRegistry;
|
||||||
import net.fortuna.ical4j.vcard.Property;
|
import net.fortuna.ical4j.vcard.Property;
|
||||||
@ -33,6 +32,7 @@ import net.fortuna.ical4j.vcard.VCard;
|
|||||||
import net.fortuna.ical4j.vcard.VCardBuilder;
|
import net.fortuna.ical4j.vcard.VCardBuilder;
|
||||||
import net.fortuna.ical4j.vcard.VCardOutputter;
|
import net.fortuna.ical4j.vcard.VCardOutputter;
|
||||||
import net.fortuna.ical4j.vcard.parameter.Type;
|
import net.fortuna.ical4j.vcard.parameter.Type;
|
||||||
|
import net.fortuna.ical4j.vcard.property.Address;
|
||||||
import net.fortuna.ical4j.vcard.property.BDay;
|
import net.fortuna.ical4j.vcard.property.BDay;
|
||||||
import net.fortuna.ical4j.vcard.property.Email;
|
import net.fortuna.ical4j.vcard.property.Email;
|
||||||
import net.fortuna.ical4j.vcard.property.Fn;
|
import net.fortuna.ical4j.vcard.property.Fn;
|
||||||
@ -45,7 +45,6 @@ import net.fortuna.ical4j.vcard.property.Uid;
|
|||||||
import net.fortuna.ical4j.vcard.property.Url;
|
import net.fortuna.ical4j.vcard.property.Url;
|
||||||
import net.fortuna.ical4j.vcard.property.Version;
|
import net.fortuna.ical4j.vcard.property.Version;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -64,7 +63,7 @@ public class Contact extends Resource {
|
|||||||
@Getter @Setter private String prefix, givenName, middleName, familyName, suffix;
|
@Getter @Setter private String prefix, givenName, middleName, familyName, suffix;
|
||||||
@Getter @Setter private String phoneticGivenName, phoneticMiddleName, phoneticFamilyName;
|
@Getter @Setter private String phoneticGivenName, phoneticMiddleName, phoneticFamilyName;
|
||||||
@Getter @Setter private String[] nickNames;
|
@Getter @Setter private String[] nickNames;
|
||||||
|
|
||||||
@Getter @Setter private byte[] photo;
|
@Getter @Setter private byte[] photo;
|
||||||
|
|
||||||
@Getter @Setter private Date birthDay;
|
@Getter @Setter private Date birthDay;
|
||||||
@ -92,6 +91,11 @@ public class Contact extends Resource {
|
|||||||
phoneNumbers.add(number);
|
phoneNumbers.add(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter private List<Address> addresses = new LinkedList<Address>();
|
||||||
|
public void addAddress(Address address) {
|
||||||
|
addresses.add(address);
|
||||||
|
}
|
||||||
|
|
||||||
@Getter private List<URI> URLs = new LinkedList<URI>();
|
@Getter private List<URI> URLs = new LinkedList<URI>();
|
||||||
public void addURL(URI url) {
|
public void addURL(URI url) {
|
||||||
URLs.add(url);
|
URLs.add(url);
|
||||||
@ -118,8 +122,6 @@ public class Contact extends Resource {
|
|||||||
propertyFactoryRegistry.register("X-" + PhoneticMiddleName.PROPERTY_NAME, new PhoneticMiddleName.Factory());
|
propertyFactoryRegistry.register("X-" + PhoneticMiddleName.PROPERTY_NAME, new PhoneticMiddleName.Factory());
|
||||||
propertyFactoryRegistry.register("X-" + PhoneticLastName.PROPERTY_NAME, new PhoneticLastName.Factory());
|
propertyFactoryRegistry.register("X-" + PhoneticLastName.PROPERTY_NAME, new PhoneticLastName.Factory());
|
||||||
|
|
||||||
//Log.d(TAG, IOUtils.toString(is));
|
|
||||||
|
|
||||||
VCardBuilder builder = new VCardBuilder(
|
VCardBuilder builder = new VCardBuilder(
|
||||||
new InputStreamReader(is),
|
new InputStreamReader(is),
|
||||||
new GroupRegistry(),
|
new GroupRegistry(),
|
||||||
@ -155,7 +157,6 @@ public class Contact extends Resource {
|
|||||||
if (nickname != null)
|
if (nickname != null)
|
||||||
nickNames = nickname.getNames();
|
nickNames = nickname.getNames();
|
||||||
|
|
||||||
// structured name
|
|
||||||
N n = (N)vcard.getProperty(Id.N);
|
N n = (N)vcard.getProperty(Id.N);
|
||||||
if (n != null) {
|
if (n != null) {
|
||||||
prefix = StringUtils.join(n.getPrefixes(), " ");
|
prefix = StringUtils.join(n.getPrefixes(), " ");
|
||||||
@ -165,7 +166,6 @@ public class Contact extends Resource {
|
|||||||
suffix = StringUtils.join(n.getSuffixes(), " ");
|
suffix = StringUtils.join(n.getSuffixes(), " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// phonetic name
|
|
||||||
PhoneticFirstName phoneticFirstName = (PhoneticFirstName)vcard.getExtendedProperty(PhoneticFirstName.PROPERTY_NAME);
|
PhoneticFirstName phoneticFirstName = (PhoneticFirstName)vcard.getExtendedProperty(PhoneticFirstName.PROPERTY_NAME);
|
||||||
if (phoneticFirstName != null)
|
if (phoneticFirstName != null)
|
||||||
phoneticGivenName = phoneticFirstName.getValue();
|
phoneticGivenName = phoneticFirstName.getValue();
|
||||||
@ -182,6 +182,9 @@ public class Contact extends Resource {
|
|||||||
for (Property p : vcard.getProperties(Id.TEL))
|
for (Property p : vcard.getProperties(Id.TEL))
|
||||||
phoneNumbers.add((Telephone)p);
|
phoneNumbers.add((Telephone)p);
|
||||||
|
|
||||||
|
for (Property p : vcard.getProperties(Id.ADR))
|
||||||
|
addresses.add((Address)p);
|
||||||
|
|
||||||
Photo photo = (Photo)vcard.getProperty(Id.PHOTO);
|
Photo photo = (Photo)vcard.getProperty(Id.PHOTO);
|
||||||
if (photo != null)
|
if (photo != null)
|
||||||
this.photo = photo.getBinary();
|
this.photo = photo.getBinary();
|
||||||
@ -236,12 +239,15 @@ public class Contact extends Resource {
|
|||||||
properties.add(new PhoneticMiddleName(phoneticMiddleName));
|
properties.add(new PhoneticMiddleName(phoneticMiddleName));
|
||||||
if (phoneticFamilyName != null)
|
if (phoneticFamilyName != null)
|
||||||
properties.add(new PhoneticLastName(phoneticFamilyName));
|
properties.add(new PhoneticLastName(phoneticFamilyName));
|
||||||
|
|
||||||
|
if (!emails.isEmpty())
|
||||||
|
properties.addAll(emails);
|
||||||
|
|
||||||
|
if (!addresses.isEmpty())
|
||||||
|
properties.addAll(addresses);
|
||||||
|
|
||||||
for (Email email : emails)
|
if (!phoneNumbers.isEmpty())
|
||||||
properties.add(email);
|
properties.addAll(phoneNumbers);
|
||||||
|
|
||||||
for (Telephone number : phoneNumbers)
|
|
||||||
properties.add(number);
|
|
||||||
|
|
||||||
for (URI uri : URLs)
|
for (URI uri : URLs)
|
||||||
properties.add(new Url(uri));
|
properties.add(new Url(uri));
|
||||||
|
@ -16,6 +16,7 @@ import java.util.List;
|
|||||||
import net.fortuna.ical4j.model.Date;
|
import net.fortuna.ical4j.model.Date;
|
||||||
import net.fortuna.ical4j.vcard.Parameter.Id;
|
import net.fortuna.ical4j.vcard.Parameter.Id;
|
||||||
import net.fortuna.ical4j.vcard.parameter.Type;
|
import net.fortuna.ical4j.vcard.parameter.Type;
|
||||||
|
import net.fortuna.ical4j.vcard.property.Address;
|
||||||
import net.fortuna.ical4j.vcard.property.Telephone;
|
import net.fortuna.ical4j.vcard.property.Telephone;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
@ -37,6 +38,7 @@ import android.provider.ContactsContract.CommonDataKinds.Note;
|
|||||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Photo;
|
import android.provider.ContactsContract.CommonDataKinds.Photo;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
||||||
|
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Website;
|
import android.provider.ContactsContract.CommonDataKinds.Website;
|
||||||
import android.provider.ContactsContract.Data;
|
import android.provider.ContactsContract.Data;
|
||||||
import android.provider.ContactsContract.RawContacts;
|
import android.provider.ContactsContract.RawContacts;
|
||||||
@ -223,6 +225,32 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
c.addPhoneNumber(number);
|
c.addPhoneNumber(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// postal addresses
|
||||||
|
cursor = providerClient.query(dataURI(), new String[] {
|
||||||
|
/* 0 */ StructuredPostal.FORMATTED_ADDRESS, StructuredPostal.TYPE,
|
||||||
|
/* 2 */ StructuredPostal.STREET, StructuredPostal.POBOX, StructuredPostal.NEIGHBORHOOD,
|
||||||
|
/* 5 */ StructuredPostal.CITY, StructuredPostal.REGION, StructuredPostal.POSTCODE,
|
||||||
|
/* 8 */ StructuredPostal.COUNTRY
|
||||||
|
}, StructuredPostal.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
|
||||||
|
new String[] { String.valueOf(c.getLocalID()), StructuredPostal.CONTENT_ITEM_TYPE }, null);
|
||||||
|
while (cursor != null && cursor.moveToNext()) {
|
||||||
|
Type[] types = new Type[] {};
|
||||||
|
switch (cursor.getInt(1)) {
|
||||||
|
case StructuredPostal.TYPE_HOME:
|
||||||
|
types = new Type[] { Type.HOME };
|
||||||
|
break;
|
||||||
|
case StructuredPostal.TYPE_WORK:
|
||||||
|
types = new Type[] { Type.WORK };
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Address address = new Address(
|
||||||
|
cursor.getString(3), cursor.getString(4), cursor.getString(2),
|
||||||
|
cursor.getString(5), cursor.getString(6), cursor.getString(7),
|
||||||
|
cursor.getString(8), types
|
||||||
|
);
|
||||||
|
c.addAddress(address);
|
||||||
|
}
|
||||||
|
|
||||||
// photo
|
// photo
|
||||||
cursor = providerClient.query(dataURI(), new String[] { Photo.PHOTO },
|
cursor = providerClient.query(dataURI(), new String[] { Photo.PHOTO },
|
||||||
Photo.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
|
Photo.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
|
||||||
@ -329,6 +357,9 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
|
|
||||||
for (Telephone number : contact.getPhoneNumbers())
|
for (Telephone number : contact.getPhoneNumbers())
|
||||||
pendingOperations.add(buildPhoneNumber(newDataInsertBuilder(localID, backrefIdx), number).build());
|
pendingOperations.add(buildPhoneNumber(newDataInsertBuilder(localID, backrefIdx), number).build());
|
||||||
|
|
||||||
|
for (Address address : contact.getAddresses())
|
||||||
|
pendingOperations.add(buildAddress(newDataInsertBuilder(localID, backrefIdx), address).build());
|
||||||
|
|
||||||
if (contact.getPhoto() != null)
|
if (contact.getPhoto() != null)
|
||||||
pendingOperations.add(buildPhoto(newDataInsertBuilder(localID, backrefIdx), contact.getPhoto()).build());
|
pendingOperations.add(buildPhoto(newDataInsertBuilder(localID, backrefIdx), contact.getPhoto()).build());
|
||||||
@ -444,6 +475,43 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
.withValue(Phone.TYPE, type);
|
.withValue(Phone.TYPE, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Builder buildAddress(Builder builder, Address address) {
|
||||||
|
/* street po.box (extended)
|
||||||
|
* region
|
||||||
|
* postal code city
|
||||||
|
* country
|
||||||
|
*/
|
||||||
|
String lineStreet = StringUtils.join(new String[] { address.getStreet(), address.getPoBox(), address.getExtended() }, " "),
|
||||||
|
lineLocality = StringUtils.join(new String[] { address.getPostcode(), address.getLocality() }, " ");
|
||||||
|
|
||||||
|
List<String> lines = new LinkedList<String>();
|
||||||
|
if (lineStreet != null)
|
||||||
|
lines.add(lineStreet);
|
||||||
|
if (address.getRegion() != null && !address.getRegion().isEmpty())
|
||||||
|
lines.add(address.getRegion());
|
||||||
|
if (lineLocality != null)
|
||||||
|
lines.add(lineLocality);
|
||||||
|
|
||||||
|
int typeCode = StructuredPostal.TYPE_OTHER;
|
||||||
|
Type type = (Type)address.getParameter(Id.TYPE);
|
||||||
|
if (type == Type.HOME)
|
||||||
|
typeCode = StructuredPostal.TYPE_HOME;
|
||||||
|
else if (type == Type.WORK)
|
||||||
|
typeCode = StructuredPostal.TYPE_WORK;
|
||||||
|
|
||||||
|
return builder
|
||||||
|
.withValue(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE)
|
||||||
|
.withValue(StructuredPostal.FORMATTED_ADDRESS, StringUtils.join(lines, "\n"))
|
||||||
|
.withValue(StructuredPostal.TYPE, typeCode)
|
||||||
|
.withValue(StructuredPostal.STREET, address.getStreet())
|
||||||
|
.withValue(StructuredPostal.POBOX, address.getPoBox())
|
||||||
|
.withValue(StructuredPostal.NEIGHBORHOOD, address.getExtended())
|
||||||
|
.withValue(StructuredPostal.CITY, address.getLocality())
|
||||||
|
.withValue(StructuredPostal.REGION, address.getRegion())
|
||||||
|
.withValue(StructuredPostal.POSTCODE, address.getPostcode())
|
||||||
|
.withValue(StructuredPostal.COUNTRY, address.getCountry());
|
||||||
|
}
|
||||||
|
|
||||||
protected Builder buildPhoto(Builder builder, byte[] photo) {
|
protected Builder buildPhoto(Builder builder, byte[] photo) {
|
||||||
return builder
|
return builder
|
||||||
.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE)
|
.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
package at.bitfire.davdroid.resource;
|
package at.bitfire.davdroid.resource;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -80,8 +81,12 @@ public abstract class RemoteCollection<ResourceType extends Resource> {
|
|||||||
for (WebDavResource member : collection.getMembers()) {
|
for (WebDavResource member : collection.getMembers()) {
|
||||||
ResourceType resource = newResourceSkeleton(member.getName(), member.getETag());
|
ResourceType resource = newResourceSkeleton(member.getName(), member.getETag());
|
||||||
try {
|
try {
|
||||||
resource.parseEntity(member.getContent());
|
InputStream is = member.getContent();
|
||||||
foundResources.add(resource);
|
if (is != null) {
|
||||||
|
resource.parseEntity(is);
|
||||||
|
foundResources.add(resource);
|
||||||
|
} else
|
||||||
|
Log.e(TAG, "Ignoring entity without content");
|
||||||
} catch (ParserException ex) {
|
} catch (ParserException ex) {
|
||||||
Log.e(TAG, "Ignoring unparseable entity in multi-response", ex);
|
Log.e(TAG, "Ignoring unparseable entity in multi-response", ex);
|
||||||
}
|
}
|
||||||
|
@ -140,12 +140,14 @@ public class WebDavResource {
|
|||||||
checkResponse(response);
|
checkResponse(response);
|
||||||
|
|
||||||
Header[] allowHeaders = response.getHeaders("Allow");
|
Header[] allowHeaders = response.getHeaders("Allow");
|
||||||
for (Header allowHeader : allowHeaders)
|
if (allowHeaders != null)
|
||||||
methods.addAll(Arrays.asList(allowHeader.getValue().split(", ?")));
|
for (Header allowHeader : allowHeaders)
|
||||||
|
methods.addAll(Arrays.asList(allowHeader.getValue().split(", ?")));
|
||||||
|
|
||||||
Header[] capHeaders = response.getHeaders("DAV");
|
Header[] capHeaders = response.getHeaders("DAV");
|
||||||
for (Header capHeader : capHeaders)
|
if (capHeaders != null)
|
||||||
capabilities.addAll(Arrays.asList(capHeader.getValue().split(", ?")));
|
for (Header capHeader : capHeaders)
|
||||||
|
capabilities.addAll(Arrays.asList(capHeader.getValue().split(", ?")));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean supportsDAV(String capability) {
|
public boolean supportsDAV(String capability) {
|
||||||
|
Loading…
Reference in New Issue
Block a user