diff options
| author | Daisuke Miyakawa <dmiyakawa@google.com> | 2009-10-27 11:22:34 +0900 |
|---|---|---|
| committer | Daisuke Miyakawa <dmiyakawa@google.com> | 2009-10-29 09:16:31 +0900 |
| commit | 837cba33c59ea4bb622878f77fc262436e01ce2b (patch) | |
| tree | 927f9d97f45eebf6d28023cc2058c4a365712f0f /core/java/android/pim | |
| parent | bb88e3ad568a05cc816fa786fcf1902fa9497499 (diff) | |
| download | frameworks_base-837cba33c59ea4bb622878f77fc262436e01ce2b.zip frameworks_base-837cba33c59ea4bb622878f77fc262436e01ce2b.tar.gz frameworks_base-837cba33c59ea4bb622878f77fc262436e01ce2b.tar.bz2 | |
Add partial support of Android-specific properties.
In the near future, all the values which cannot be converted to
vCard property is expressed as "X-ANDROID-CUSTOM" property + MIME_TYPE.
Example (Nick name):
X-ANDROID-CUSTOM:vnd.android.cursor.item/nickname;Nicky;;;;;;;;;;;;;
All the data are stored ordered by its column name ("data1" - "data15").
Currently the code assumes the max num is 15.
Internal Issue number: 2079082
Diffstat (limited to 'core/java/android/pim')
| -rw-r--r-- | core/java/android/pim/vcard/Constants.java | 6 | ||||
| -rw-r--r-- | core/java/android/pim/vcard/ContactStruct.java | 53 | ||||
| -rw-r--r-- | core/java/android/pim/vcard/VCardComposer.java | 144 |
3 files changed, 173 insertions, 30 deletions
diff --git a/core/java/android/pim/vcard/Constants.java b/core/java/android/pim/vcard/Constants.java index a1c7e10..052f329 100644 --- a/core/java/android/pim/vcard/Constants.java +++ b/core/java/android/pim/vcard/Constants.java @@ -72,6 +72,9 @@ package android.pim.vcard; // Phone number for Skype, available as usual phone. public static final String PROPERTY_X_SKYPE_PSTNNUMBER = "X-SKYPE-PSTNNUMBER"; + // Property for Android-specific fields. + public static final String PROPERTY_X_ANDROID_CUSTOM = "X-ANDROID-CUSTOM"; + // Properties for DoCoMo vCard. public static final String PROPERTY_X_CLASS = "X-CLASS"; public static final String PROPERTY_X_REDUCTION = "X-REDUCTION"; @@ -158,6 +161,9 @@ package android.pim.vcard; public static final String PROPERTY_X_GOOGLE_TALK_WITH_SPACE = "X-GOOGLE TALK"; } + // TODO: Should be in ContactsContract? + /* package */ static final int MAX_DATA_COLUMN = 15; + private Constants() { } }
\ No newline at end of file diff --git a/core/java/android/pim/vcard/ContactStruct.java b/core/java/android/pim/vcard/ContactStruct.java index eb9c48a..9d40db6 100644 --- a/core/java/android/pim/vcard/ContactStruct.java +++ b/core/java/android/pim/vcard/ContactStruct.java @@ -442,7 +442,8 @@ public class ContactStruct { private List<ImData> mImList; private List<PhotoData> mPhotoList; private List<String> mWebsiteList; - + private List<List<String>> mAndroidCustomPropertyList; + private final int mVCardType; private final Account mAccount; @@ -928,14 +929,19 @@ public class ContactStruct { mWebsiteList = new ArrayList<String>(1); } mWebsiteList.add(propValue); + } else if (propName.equals(Constants.PROPERTY_BDAY)) { + mBirthday = propValue; } else if (propName.equals(Constants.PROPERTY_X_PHONETIC_FIRST_NAME)) { mPhoneticGivenName = propValue; } else if (propName.equals(Constants.PROPERTY_X_PHONETIC_MIDDLE_NAME)) { mPhoneticMiddleName = propValue; } else if (propName.equals(Constants.PROPERTY_X_PHONETIC_LAST_NAME)) { mPhoneticFamilyName = propValue; - } else if (propName.equals(Constants.PROPERTY_BDAY)) { - mBirthday = propValue; + } else if (propName.equals(Constants.PROPERTY_X_ANDROID_CUSTOM)) { + final List<String> customPropertyList = + VCardUtils.constructListFromValue(propValue, + VCardConfig.isV30(mVCardType)); + handleAndroidCustomProperty(customPropertyList); /*} else if (propName.equals("REV")) { // Revision of this VCard entry. I think we can ignore this. } else if (propName.equals("UID")) { @@ -963,6 +969,13 @@ public class ContactStruct { } } + private void handleAndroidCustomProperty(final List<String> customPropertyList) { + if (mAndroidCustomPropertyList == null) { + mAndroidCustomPropertyList = new ArrayList<List<String>>(); + } + mAndroidCustomPropertyList.add(customPropertyList); + } + /** * Construct the display name. The constructed data must not be null. */ @@ -1017,7 +1030,7 @@ public class ContactStruct { mDisplayName = ""; } } - + /** * Consolidate several fielsds (like mName) using name candidates, */ @@ -1028,7 +1041,7 @@ public class ContactStruct { mPhoneticFullName = mPhoneticFullName.trim(); } } - + // From GoogleSource.java in Contacts app. private static final String ACCOUNT_TYPE_GOOGLE = "com.google"; private static final String GOOGLE_MY_CONTACTS_GROUP = "System Group: My Contacts"; @@ -1224,6 +1237,36 @@ public class ContactStruct { operationList.add(builder.build()); } + if (mAndroidCustomPropertyList != null) { + for (List<String> customPropertyList : mAndroidCustomPropertyList) { + int size = customPropertyList.size(); + if (size < 2 || TextUtils.isEmpty(customPropertyList.get(0))) { + continue; + } else if (size > Constants.MAX_DATA_COLUMN + 1) { + size = Constants.MAX_DATA_COLUMN + 1; + customPropertyList = + customPropertyList.subList(0, Constants.MAX_DATA_COLUMN + 2); + } + + int i = 0; + for (final String customPropertyValue : customPropertyList) { + if (i == 0) { + final String mimeType = customPropertyValue; + builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); + builder.withValueBackReference(GroupMembership.RAW_CONTACT_ID, 0); + builder.withValue(Data.MIMETYPE, mimeType); + } else { // 1 <= i && i <= MAX_DATA_COLUMNS + if (!TextUtils.isEmpty(customPropertyValue)) { + builder.withValue("data" + i, customPropertyValue); + } + } + + operationList.add(builder.build()); + i++; + } + } + } + if (myGroupsId != null) { builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); builder.withValueBackReference(GroupMembership.RAW_CONTACT_ID, 0); diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java index 8eabd4b..33581c9 100644 --- a/core/java/android/pim/vcard/VCardComposer.java +++ b/core/java/android/pim/vcard/VCardComposer.java @@ -1019,11 +1019,11 @@ public class VCardComposer { return; } - final String propertyNickname; + final boolean useAndroidProperty; if (mIsV30) { - propertyNickname = Constants.PROPERTY_NICKNAME; - /*} else if (mUsesAndroidProperty) { - propertyNickname = VCARD_PROPERTY_X_NICKNAME;*/ + useAndroidProperty = false; + } else if (mUsesAndroidProperty) { + useAndroidProperty = true; } else { // There's no way to add this field. return; @@ -1034,29 +1034,13 @@ public class VCardComposer { if (TextUtils.isEmpty(nickname)) { continue; } - - final String encodedNickname; - final boolean reallyUseQuotedPrintable = - (mUsesQuotedPrintable && - !VCardUtils.containsOnlyNonCrLfPrintableAscii(nickname)); - if (reallyUseQuotedPrintable) { - encodedNickname = encodeQuotedPrintable(nickname); + if (useAndroidProperty) { + appendAndroidSpecificProperty(builder, Nickname.CONTENT_ITEM_TYPE, + contentValues); } else { - encodedNickname = escapeCharacters(nickname); - } - - builder.append(propertyNickname); - if (shouldAppendCharsetAttribute(propertyNickname)) { - builder.append(VCARD_ATTR_SEPARATOR); - builder.append(mVCardAttributeCharset); - } - if (reallyUseQuotedPrintable) { - builder.append(VCARD_ATTR_SEPARATOR); - builder.append(VCARD_ATTR_ENCODING_QP); + appendVCardLineWithCharsetAndQPDetection(builder, + Constants.PROPERTY_NICKNAME, nickname); } - builder.append(VCARD_DATA_SEPARATOR); - builder.append(encodedNickname); - builder.append(VCARD_COL_SEPARATOR); } } @@ -1491,6 +1475,33 @@ public class VCardComposer { } } + private void appendAndroidSpecificProperty(final StringBuilder builder, + final String mimeType, ContentValues contentValues) { + List<String> rawDataList = new ArrayList<String>(); + rawDataList.add(mimeType); + final List<String> columnNameList; + if (Nickname.CONTENT_ITEM_TYPE.equals(mimeType)) { + + } else { + // If you add the other field, please check all the columns are able to be + // converted to String. + // + // e.g. BLOB is not what we can handle here now. + return; + } + + for (int i = 0; i < Constants.MAX_DATA_COLUMN; i++) { + String value = contentValues.getAsString("data" + i); + if (value == null) { + value = ""; + } + rawDataList.add(value); + } + + appendVCardLineWithCharsetAndQPDetection(builder, + Constants.PROPERTY_X_ANDROID_CUSTOM, rawDataList); + } + /** * Append '\' to the characters which should be escaped. The character set is different * not only between vCard 2.1 and vCard 3.0 but also among each device. @@ -1968,6 +1979,8 @@ public class VCardComposer { } } + // appendVCardLine() variants accepting one String. + private void appendVCardLineWithCharsetAndQPDetection(final StringBuilder builder, final String propertyName, final String rawData) { appendVCardLineWithCharsetAndQPDetection(builder, propertyName, null, rawData); @@ -2026,6 +2039,87 @@ public class VCardComposer { builder.append(VCARD_COL_SEPARATOR); } + // appendVCardLine() variants accepting List<String>. + + private void appendVCardLineWithCharsetAndQPDetection(final StringBuilder builder, + final String propertyName, final List<String> rawDataList) { + appendVCardLineWithCharsetAndQPDetection(builder, propertyName, null, rawDataList); + } + + private void appendVCardLineWithCharsetAndQPDetection(final StringBuilder builder, + final String propertyName, + final List<String> attributeList, final List<String> rawDataList) { + boolean needCharset = false; + boolean reallyUseQuotedPrintable = false; + for (String rawData : rawDataList) { + if (!needCharset && mUsesQuotedPrintable && + !VCardUtils.containsOnlyPrintableAscii(rawData)) { + needCharset = true; + } + if (!reallyUseQuotedPrintable && + !VCardUtils.containsOnlyNonCrLfPrintableAscii(rawData)) { + reallyUseQuotedPrintable = true; + } + if (needCharset && reallyUseQuotedPrintable) { + break; + } + } + + appendVCardLine(builder, propertyName, attributeList, + rawDataList, needCharset, reallyUseQuotedPrintable); + } + + /* + private void appendVCardLine(final StringBuilder builder, + final String propertyName, final List<String> rawDataList) { + appendVCardLine(builder, propertyName, rawDataList, false, false); + } + + private void appendVCardLine(final StringBuilder builder, + final String propertyName, final List<String> rawDataList, + final boolean needCharset, boolean needQuotedPrintable) { + appendVCardLine(builder, propertyName, null, rawDataList, needCharset, needQuotedPrintable); + }*/ + + private void appendVCardLine(final StringBuilder builder, + final String propertyName, + final List<String> attributeList, + final List<String> rawDataList, final boolean needCharset, + boolean needQuotedPrintable) { + builder.append(propertyName); + if (attributeList != null && attributeList.size() > 0) { + builder.append(VCARD_ATTR_SEPARATOR); + appendTypeAttributes(builder, attributeList); + } + if (needCharset) { + builder.append(VCARD_ATTR_SEPARATOR); + builder.append(mVCardAttributeCharset); + } + + builder.append(VCARD_DATA_SEPARATOR); + boolean first = true; + for (String rawData : rawDataList) { + final String encodedData; + if (needQuotedPrintable) { + builder.append(VCARD_ATTR_SEPARATOR); + builder.append(VCARD_ATTR_ENCODING_QP); + encodedData = encodeQuotedPrintable(rawData); + } else { + // TODO: one line may be too huge, which may be invalid in vCard spec, though + // several (even well-known) applications do not care this. + encodedData = escapeCharacters(rawData); + } + + if (first) { + first = false; + } else { + builder.append(VCARD_ITEM_SEPARATOR); + } + builder.append(encodedData); + } + builder.append(VCARD_COL_SEPARATOR); + } + /** * VCARD_ATTR_SEPARATOR must be appended before this method being called. */ |
