Merge change 26944 into eclair
* changes: Add "TYPE=" to type attribute when appropriate.
This commit is contained in:
@@ -24,6 +24,8 @@ import android.content.Entity.NamedContentValues;
|
|||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteException;
|
import android.database.sqlite.SQLiteException;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import android.provider.CallLog;
|
||||||
|
import android.provider.CallLog.Calls;
|
||||||
import android.provider.ContactsContract.Contacts;
|
import android.provider.ContactsContract.Contacts;
|
||||||
import android.provider.ContactsContract.Data;
|
import android.provider.ContactsContract.Data;
|
||||||
import android.provider.ContactsContract.RawContacts;
|
import android.provider.ContactsContract.RawContacts;
|
||||||
@@ -38,11 +40,8 @@ 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.StructuredPostal;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Website;
|
import android.provider.ContactsContract.CommonDataKinds.Website;
|
||||||
import android.provider.CallLog.Calls;
|
|
||||||
import android.provider.CallLog;
|
|
||||||
import android.text.format.DateUtils;
|
|
||||||
import android.text.format.Time;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.text.format.Time;
|
||||||
import android.util.CharsetUtils;
|
import android.util.CharsetUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -82,6 +81,8 @@ import java.util.Map;
|
|||||||
public class VCardComposer {
|
public class VCardComposer {
|
||||||
private static final String LOG_TAG = "vcard.VCardComposer";
|
private static final String LOG_TAG = "vcard.VCardComposer";
|
||||||
|
|
||||||
|
private final static String DEFAULT_EMAIL_TYPE = Constants.ATTR_TYPE_INTERNET;
|
||||||
|
|
||||||
public static interface OneEntryHandler {
|
public static interface OneEntryHandler {
|
||||||
public boolean onInit(Context context);
|
public boolean onInit(Context context);
|
||||||
|
|
||||||
@@ -403,7 +404,7 @@ public class VCardComposer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns true when initialization is successful and all the other
|
* @return Returns true when initialization is successful and all the other
|
||||||
* methods are available. Returns false otherwise.
|
* methods are available. Returns false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean init(final String selection, final String[] selectionArgs) {
|
public boolean init(final String selection, final String[] selectionArgs) {
|
||||||
if (mCareHandlerErrors) {
|
if (mCareHandlerErrors) {
|
||||||
@@ -554,7 +555,7 @@ public class VCardComposer {
|
|||||||
final long dateAsLong = mCursor.getLong(DATE_COLUMN_INDEX);
|
final long dateAsLong = mCursor.getLong(DATE_COLUMN_INDEX);
|
||||||
builder.append(VCARD_PROPERTY_X_TIMESTAMP);
|
builder.append(VCARD_PROPERTY_X_TIMESTAMP);
|
||||||
builder.append(VCARD_ATTR_SEPARATOR);
|
builder.append(VCARD_ATTR_SEPARATOR);
|
||||||
appendType(builder, callLogTypeStr);
|
appendTypeAttribute(builder, callLogTypeStr);
|
||||||
builder.append(VCARD_DATA_SEPARATOR);
|
builder.append(VCARD_DATA_SEPARATOR);
|
||||||
builder.append(toRfc2455Format(dateAsLong));
|
builder.append(toRfc2455Format(dateAsLong));
|
||||||
builder.append(VCARD_COL_SEPARATOR);
|
builder.append(VCARD_COL_SEPARATOR);
|
||||||
@@ -705,9 +706,9 @@ public class VCardComposer {
|
|||||||
return mErrorReason;
|
return mErrorReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendStructuredNames(StringBuilder builder,
|
private void appendStructuredNames(final StringBuilder builder,
|
||||||
final Map<String, List<ContentValues>> contentValuesListMap) {
|
final Map<String, List<ContentValues>> contentValuesListMap) {
|
||||||
List<ContentValues> contentValuesList = contentValuesListMap
|
final List<ContentValues> contentValuesList = contentValuesListMap
|
||||||
.get(StructuredName.CONTENT_ITEM_TYPE);
|
.get(StructuredName.CONTENT_ITEM_TYPE);
|
||||||
if (contentValuesList != null) {
|
if (contentValuesList != null) {
|
||||||
appendStructuredNamesInternal(builder, contentValuesList);
|
appendStructuredNamesInternal(builder, contentValuesList);
|
||||||
@@ -922,7 +923,7 @@ public class VCardComposer {
|
|||||||
|
|
||||||
private void appendNickNames(final StringBuilder builder,
|
private void appendNickNames(final StringBuilder builder,
|
||||||
final Map<String, List<ContentValues>> contentValuesListMap) {
|
final Map<String, List<ContentValues>> contentValuesListMap) {
|
||||||
List<ContentValues> contentValuesList = contentValuesListMap
|
final List<ContentValues> contentValuesList = contentValuesListMap
|
||||||
.get(Nickname.CONTENT_ITEM_TYPE);
|
.get(Nickname.CONTENT_ITEM_TYPE);
|
||||||
if (contentValuesList != null) {
|
if (contentValuesList != null) {
|
||||||
final String propertyNickname;
|
final String propertyNickname;
|
||||||
@@ -958,7 +959,7 @@ public class VCardComposer {
|
|||||||
|
|
||||||
private void appendPhones(final StringBuilder builder,
|
private void appendPhones(final StringBuilder builder,
|
||||||
final Map<String, List<ContentValues>> contentValuesListMap) {
|
final Map<String, List<ContentValues>> contentValuesListMap) {
|
||||||
List<ContentValues> contentValuesList = contentValuesListMap
|
final List<ContentValues> contentValuesList = contentValuesListMap
|
||||||
.get(Phone.CONTENT_ITEM_TYPE);
|
.get(Phone.CONTENT_ITEM_TYPE);
|
||||||
if (contentValuesList != null) {
|
if (contentValuesList != null) {
|
||||||
for (ContentValues contentValues : contentValuesList) {
|
for (ContentValues contentValues : contentValuesList) {
|
||||||
@@ -976,7 +977,7 @@ public class VCardComposer {
|
|||||||
|
|
||||||
private void appendEmails(final StringBuilder builder,
|
private void appendEmails(final StringBuilder builder,
|
||||||
final Map<String, List<ContentValues>> contentValuesListMap) {
|
final Map<String, List<ContentValues>> contentValuesListMap) {
|
||||||
List<ContentValues> contentValuesList = contentValuesListMap
|
final List<ContentValues> contentValuesList = contentValuesListMap
|
||||||
.get(Email.CONTENT_ITEM_TYPE);
|
.get(Email.CONTENT_ITEM_TYPE);
|
||||||
if (contentValuesList != null) {
|
if (contentValuesList != null) {
|
||||||
for (ContentValues contentValues : contentValuesList) {
|
for (ContentValues contentValues : contentValuesList) {
|
||||||
@@ -992,7 +993,7 @@ public class VCardComposer {
|
|||||||
|
|
||||||
private void appendPostals(final StringBuilder builder,
|
private void appendPostals(final StringBuilder builder,
|
||||||
final Map<String, List<ContentValues>> contentValuesListMap) {
|
final Map<String, List<ContentValues>> contentValuesListMap) {
|
||||||
List<ContentValues> contentValuesList = contentValuesListMap
|
final List<ContentValues> contentValuesList = contentValuesListMap
|
||||||
.get(StructuredPostal.CONTENT_ITEM_TYPE);
|
.get(StructuredPostal.CONTENT_ITEM_TYPE);
|
||||||
|
|
||||||
if (contentValuesList != null) {
|
if (contentValuesList != null) {
|
||||||
@@ -1062,7 +1063,7 @@ public class VCardComposer {
|
|||||||
|
|
||||||
private void appendIms(final StringBuilder builder,
|
private void appendIms(final StringBuilder builder,
|
||||||
final Map<String, List<ContentValues>> contentValuesListMap) {
|
final Map<String, List<ContentValues>> contentValuesListMap) {
|
||||||
List<ContentValues> contentValuesList = contentValuesListMap
|
final List<ContentValues> contentValuesList = contentValuesListMap
|
||||||
.get(Im.CONTENT_ITEM_TYPE);
|
.get(Im.CONTENT_ITEM_TYPE);
|
||||||
if (contentValuesList != null) {
|
if (contentValuesList != null) {
|
||||||
for (ContentValues contentValues : contentValuesList) {
|
for (ContentValues contentValues : contentValuesList) {
|
||||||
@@ -1081,7 +1082,7 @@ public class VCardComposer {
|
|||||||
|
|
||||||
private void appendWebsites(final StringBuilder builder,
|
private void appendWebsites(final StringBuilder builder,
|
||||||
final Map<String, List<ContentValues>> contentValuesListMap) {
|
final Map<String, List<ContentValues>> contentValuesListMap) {
|
||||||
List<ContentValues> contentValuesList = contentValuesListMap
|
final List<ContentValues> contentValuesList = contentValuesListMap
|
||||||
.get(Website.CONTENT_ITEM_TYPE);
|
.get(Website.CONTENT_ITEM_TYPE);
|
||||||
if (contentValuesList != null) {
|
if (contentValuesList != null) {
|
||||||
for (ContentValues contentValues : contentValuesList) {
|
for (ContentValues contentValues : contentValuesList) {
|
||||||
@@ -1093,7 +1094,7 @@ public class VCardComposer {
|
|||||||
|
|
||||||
private void appendBirthday(final StringBuilder builder,
|
private void appendBirthday(final StringBuilder builder,
|
||||||
final Map<String, List<ContentValues>> contentValuesListMap) {
|
final Map<String, List<ContentValues>> contentValuesListMap) {
|
||||||
List<ContentValues> contentValuesList = contentValuesListMap
|
final List<ContentValues> contentValuesList = contentValuesListMap
|
||||||
.get(Miscellaneous.CONTENT_ITEM_TYPE);
|
.get(Miscellaneous.CONTENT_ITEM_TYPE);
|
||||||
if (contentValuesList != null && contentValuesList.size() > 0) {
|
if (contentValuesList != null && contentValuesList.size() > 0) {
|
||||||
// Theoretically, there must be only one birthday for each vCard data and
|
// Theoretically, there must be only one birthday for each vCard data and
|
||||||
@@ -1106,7 +1107,7 @@ public class VCardComposer {
|
|||||||
|
|
||||||
private void appendOrganizations(final StringBuilder builder,
|
private void appendOrganizations(final StringBuilder builder,
|
||||||
final Map<String, List<ContentValues>> contentValuesListMap) {
|
final Map<String, List<ContentValues>> contentValuesListMap) {
|
||||||
List<ContentValues> contentValuesList = contentValuesListMap
|
final List<ContentValues> contentValuesList = contentValuesListMap
|
||||||
.get(Organization.CONTENT_ITEM_TYPE);
|
.get(Organization.CONTENT_ITEM_TYPE);
|
||||||
if (contentValuesList != null) {
|
if (contentValuesList != null) {
|
||||||
for (ContentValues contentValues : contentValuesList) {
|
for (ContentValues contentValues : contentValuesList) {
|
||||||
@@ -1124,7 +1125,7 @@ public class VCardComposer {
|
|||||||
|
|
||||||
private void appendPhotos(final StringBuilder builder,
|
private void appendPhotos(final StringBuilder builder,
|
||||||
final Map<String, List<ContentValues>> contentValuesListMap) {
|
final Map<String, List<ContentValues>> contentValuesListMap) {
|
||||||
List<ContentValues> contentValuesList = contentValuesListMap
|
final List<ContentValues> contentValuesList = contentValuesListMap
|
||||||
.get(Photo.CONTENT_ITEM_TYPE);
|
.get(Photo.CONTENT_ITEM_TYPE);
|
||||||
if (contentValuesList != null) {
|
if (contentValuesList != null) {
|
||||||
for (ContentValues contentValues : contentValuesList) {
|
for (ContentValues contentValues : contentValuesList) {
|
||||||
@@ -1153,7 +1154,7 @@ public class VCardComposer {
|
|||||||
Log.d(LOG_TAG, "Unknown photo type. Ignore.");
|
Log.d(LOG_TAG, "Unknown photo type. Ignore.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String photoString = VCardUtils.encodeBase64(data);
|
final String photoString = VCardUtils.encodeBase64(data);
|
||||||
if (photoString.length() > 0) {
|
if (photoString.length() > 0) {
|
||||||
appendVCardPhotoLine(builder, photoString, photoType);
|
appendVCardPhotoLine(builder, photoString, photoType);
|
||||||
}
|
}
|
||||||
@@ -1201,64 +1202,76 @@ public class VCardComposer {
|
|||||||
* Note that Quoted-Printable string must not be input here.
|
* Note that Quoted-Printable string must not be input here.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("fallthrough")
|
@SuppressWarnings("fallthrough")
|
||||||
private String escapeCharacters(String unescaped) {
|
private String escapeCharacters(final String unescaped) {
|
||||||
if (TextUtils.isEmpty(unescaped)) {
|
if (TextUtils.isEmpty(unescaped)) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
final StringBuilder tmpBuilder = new StringBuilder();
|
||||||
final int length = unescaped.length();
|
final int length = unescaped.length();
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
char ch = unescaped.charAt(i);
|
char ch = unescaped.charAt(i);
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ';':
|
case ';': {
|
||||||
builder.append('\\');
|
tmpBuilder.append('\\');
|
||||||
builder.append(';');
|
tmpBuilder.append(';');
|
||||||
break;
|
break;
|
||||||
case '\r':
|
}
|
||||||
if (i + 1 < length) {
|
case '\r': {
|
||||||
char nextChar = unescaped.charAt(i);
|
if (i + 1 < length) {
|
||||||
if (nextChar == '\n') {
|
char nextChar = unescaped.charAt(i);
|
||||||
continue;
|
if (nextChar == '\n') {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// fall through
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// fall through
|
// fall through
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// fall through
|
|
||||||
}
|
}
|
||||||
case '\n':
|
case '\n': {
|
||||||
// In vCard 2.1, there's no specification about this, while
|
// In vCard 2.1, there's no specification about this, while
|
||||||
// vCard 3.0 explicitly
|
// vCard 3.0 explicitly requires this should be encoded to "\n".
|
||||||
// requires this should be encoded to "\n".
|
tmpBuilder.append("\\n");
|
||||||
builder.append("\\n");
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
if (mIsV30) {
|
|
||||||
builder.append("\\\\");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '<':
|
case '\\': {
|
||||||
case '>':
|
if (mIsV30) {
|
||||||
if (mIsDoCoMo) {
|
tmpBuilder.append("\\\\");
|
||||||
builder.append('\\');
|
break;
|
||||||
builder.append(ch);
|
} else {
|
||||||
|
// fall through
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
case '<':
|
||||||
case ',':
|
case '>': {
|
||||||
if (mIsV30) {
|
if (mIsDoCoMo) {
|
||||||
builder.append("\\,");
|
tmpBuilder.append('\\');
|
||||||
|
tmpBuilder.append(ch);
|
||||||
|
} else {
|
||||||
|
tmpBuilder.append(ch);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ',': {
|
||||||
|
if (mIsV30) {
|
||||||
|
tmpBuilder.append("\\,");
|
||||||
|
} else {
|
||||||
|
tmpBuilder.append(ch);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
tmpBuilder.append(ch);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
builder.append(ch);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.toString();
|
return tmpBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendVCardPhotoLine(StringBuilder builder,
|
private void appendVCardPhotoLine(final StringBuilder builder,
|
||||||
String encodedData, String type) {
|
final String encodedData, final String photoType) {
|
||||||
StringBuilder tmpBuilder = new StringBuilder();
|
StringBuilder tmpBuilder = new StringBuilder();
|
||||||
tmpBuilder.append(VCARD_PROPERTY_PHOTO);
|
tmpBuilder.append(VCARD_PROPERTY_PHOTO);
|
||||||
tmpBuilder.append(VCARD_ATTR_SEPARATOR);
|
tmpBuilder.append(VCARD_ATTR_SEPARATOR);
|
||||||
@@ -1268,14 +1281,15 @@ public class VCardComposer {
|
|||||||
tmpBuilder.append(VCARD_ATTR_ENCODING_BASE64_V21);
|
tmpBuilder.append(VCARD_ATTR_ENCODING_BASE64_V21);
|
||||||
}
|
}
|
||||||
tmpBuilder.append(VCARD_ATTR_SEPARATOR);
|
tmpBuilder.append(VCARD_ATTR_SEPARATOR);
|
||||||
appendType(tmpBuilder, type);
|
appendTypeAttribute(tmpBuilder, photoType);
|
||||||
tmpBuilder.append(VCARD_DATA_SEPARATOR);
|
tmpBuilder.append(VCARD_DATA_SEPARATOR);
|
||||||
tmpBuilder.append(encodedData);
|
tmpBuilder.append(encodedData);
|
||||||
|
|
||||||
String tmpStr = tmpBuilder.toString();
|
final String tmpStr = tmpBuilder.toString();
|
||||||
tmpBuilder = new StringBuilder();
|
tmpBuilder = new StringBuilder();
|
||||||
int lineCount = 0;
|
int lineCount = 0;
|
||||||
for (int i = 0; i < tmpStr.length(); i++) {
|
int length = tmpStr.length();
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
tmpBuilder.append(tmpStr.charAt(i));
|
tmpBuilder.append(tmpStr.charAt(i));
|
||||||
lineCount++;
|
lineCount++;
|
||||||
if (lineCount > 72) {
|
if (lineCount > 72) {
|
||||||
@@ -1289,7 +1303,8 @@ public class VCardComposer {
|
|||||||
builder.append(VCARD_COL_SEPARATOR);
|
builder.append(VCARD_COL_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendVCardPostalLine(StringBuilder builder, Integer type, String label,
|
private void appendVCardPostalLine(final StringBuilder builder,
|
||||||
|
final Integer typeAsObject, final String label,
|
||||||
final ContentValues contentValues) {
|
final ContentValues contentValues) {
|
||||||
builder.append(VCARD_PROPERTY_ADR);
|
builder.append(VCARD_PROPERTY_ADR);
|
||||||
builder.append(VCARD_ATTR_SEPARATOR);
|
builder.append(VCARD_ATTR_SEPARATOR);
|
||||||
@@ -1310,48 +1325,59 @@ public class VCardComposer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == null) {
|
final int typeAsPrimitive;
|
||||||
type = StructuredPostal.TYPE_OTHER;
|
if (typeAsObject == null) {
|
||||||
|
typeAsPrimitive = StructuredPostal.TYPE_OTHER;
|
||||||
|
} else {
|
||||||
|
typeAsPrimitive = typeAsObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean typeIsAppended = false;
|
String typeAsString = null;
|
||||||
switch (type) {
|
switch (typeAsPrimitive) {
|
||||||
case StructuredPostal.TYPE_HOME:
|
case StructuredPostal.TYPE_HOME: {
|
||||||
builder.append(Constants.ATTR_TYPE_HOME);
|
typeAsString = Constants.ATTR_TYPE_HOME;
|
||||||
typeIsAppended = true;
|
break;
|
||||||
break;
|
|
||||||
case StructuredPostal.TYPE_WORK:
|
|
||||||
builder.append(Constants.ATTR_TYPE_WORK);
|
|
||||||
typeIsAppended = true;
|
|
||||||
break;
|
|
||||||
case StructuredPostal.TYPE_CUSTOM:
|
|
||||||
if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
|
|
||||||
&& VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
|
|
||||||
// We're not sure whether the label is valid in the spec ("IANA-token" in the vCard 3.1
|
|
||||||
// is unclear...)
|
|
||||||
// Just for safety, we add "X-" at the beggining of each label.
|
|
||||||
// Also checks the label obeys with vCard 3.0 spec.
|
|
||||||
builder.append("X-");
|
|
||||||
builder.append(label);
|
|
||||||
builder.append(VCARD_DATA_SEPARATOR);
|
|
||||||
}
|
}
|
||||||
break;
|
case StructuredPostal.TYPE_WORK: {
|
||||||
case StructuredPostal.TYPE_OTHER:
|
typeAsString = Constants.ATTR_TYPE_WORK;
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
Log.e(LOG_TAG, "Unknown StructuredPostal type: " + type);
|
case StructuredPostal.TYPE_CUSTOM: {
|
||||||
break;
|
if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
|
||||||
|
&& VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
|
||||||
|
// We're not sure whether the label is valid in the spec
|
||||||
|
// ("IANA-token" in the vCard 3.0 is unclear...)
|
||||||
|
// Just for safety, we add "X-" at the beggining of each label.
|
||||||
|
// Also checks the label obeys with vCard 3.0 spec.
|
||||||
|
builder.append("X-");
|
||||||
|
builder.append(label);
|
||||||
|
builder.append(VCARD_DATA_SEPARATOR);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case StructuredPostal.TYPE_OTHER: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
Log.e(LOG_TAG, "Unknown StructuredPostal type: " + typeAsPrimitive);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeAsString != null) {
|
||||||
|
appendTypeAttribute(builder, typeAsString);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataExists) {
|
if (dataExists) {
|
||||||
if (typeIsAppended) {
|
// Strictly, vCard 3.0 does not allow exporters to emit charset information,
|
||||||
|
// but we will add it since the information should be useful for importers,
|
||||||
|
//
|
||||||
|
// Assume no parser does not emit error with this attribute in vCard 3.0.
|
||||||
|
if (typeAsString != null) {
|
||||||
builder.append(VCARD_ATTR_SEPARATOR);
|
builder.append(VCARD_ATTR_SEPARATOR);
|
||||||
}
|
}
|
||||||
// Strictly, vCard 3.0 does not allow this, but we add this since
|
|
||||||
// this information
|
|
||||||
// should be useful, Assume no parser does not emit error with this
|
|
||||||
// attribute.
|
|
||||||
builder.append(mVCardAttributeCharset);
|
builder.append(mVCardAttributeCharset);
|
||||||
|
|
||||||
if (useQuotedPrintable) {
|
if (useQuotedPrintable) {
|
||||||
builder.append(VCARD_ATTR_SEPARATOR);
|
builder.append(VCARD_ATTR_SEPARATOR);
|
||||||
builder.append(VCARD_ATTR_ENCODING_QP);
|
builder.append(VCARD_ATTR_ENCODING_QP);
|
||||||
@@ -1381,61 +1407,78 @@ public class VCardComposer {
|
|||||||
builder.append(VCARD_COL_SEPARATOR);
|
builder.append(VCARD_COL_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendVCardEmailLine(StringBuilder builder, Integer type, String label, String data) {
|
private void appendVCardEmailLine(final StringBuilder builder,
|
||||||
|
final Integer typeAsObject, final String label, final String data) {
|
||||||
builder.append(VCARD_PROPERTY_EMAIL);
|
builder.append(VCARD_PROPERTY_EMAIL);
|
||||||
builder.append(VCARD_ATTR_SEPARATOR);
|
|
||||||
|
|
||||||
if (type == null) {
|
final int typeAsPrimitive;
|
||||||
type = Email.TYPE_OTHER;
|
if (typeAsObject == null) {
|
||||||
|
typeAsPrimitive = Email.TYPE_OTHER;
|
||||||
|
} else {
|
||||||
|
typeAsPrimitive = typeAsObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
final String typeAsString;
|
||||||
case Email.TYPE_CUSTOM:
|
switch (typeAsPrimitive) {
|
||||||
if (android.provider.Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME
|
case Email.TYPE_CUSTOM: {
|
||||||
|
// For backward compatibility.
|
||||||
|
// Detail: Until Donut, there isn't TYPE_MOBILE for email while there is now.
|
||||||
|
// To support mobile type at that time, this custom label had been used.
|
||||||
|
if (android.provider.Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME
|
||||||
.equals(label)) {
|
.equals(label)) {
|
||||||
builder.append(Constants.ATTR_TYPE_CELL);
|
typeAsString = Constants.ATTR_TYPE_CELL;
|
||||||
} else if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
|
} else if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
|
||||||
&& VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
|
&& VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
|
||||||
builder.append("X-");
|
typeAsString = "X-" + label;
|
||||||
builder.append(label);
|
} else {
|
||||||
} else {
|
typeAsString = DEFAULT_EMAIL_TYPE;
|
||||||
// Default to INTERNET.
|
}
|
||||||
builder.append(Constants.ATTR_TYPE_INTERNET);
|
break;
|
||||||
|
}
|
||||||
|
case Email.TYPE_HOME: {
|
||||||
|
typeAsString = Constants.ATTR_TYPE_HOME;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Email.TYPE_WORK: {
|
||||||
|
typeAsString = Constants.ATTR_TYPE_WORK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Email.TYPE_OTHER: {
|
||||||
|
typeAsString = DEFAULT_EMAIL_TYPE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Email.TYPE_MOBILE: {
|
||||||
|
typeAsString = Constants.ATTR_TYPE_CELL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
Log.e(LOG_TAG, "Unknown Email type: " + typeAsPrimitive);
|
||||||
|
typeAsString = DEFAULT_EMAIL_TYPE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case Email.TYPE_HOME:
|
|
||||||
builder.append(Constants.ATTR_TYPE_HOME);
|
|
||||||
break;
|
|
||||||
case Email.TYPE_WORK:
|
|
||||||
builder.append(Constants.ATTR_TYPE_WORK);
|
|
||||||
break;
|
|
||||||
case Email.TYPE_OTHER:
|
|
||||||
builder.append(Constants.ATTR_TYPE_INTERNET);
|
|
||||||
break;
|
|
||||||
case Email.TYPE_MOBILE:
|
|
||||||
builder.append(Constants.ATTR_TYPE_CELL);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Log.e(LOG_TAG, "Unknown Email type: " + type);
|
|
||||||
builder.append(Constants.ATTR_TYPE_INTERNET);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builder.append(VCARD_ATTR_SEPARATOR);
|
||||||
|
appendTypeAttribute(builder, typeAsString);
|
||||||
builder.append(VCARD_DATA_SEPARATOR);
|
builder.append(VCARD_DATA_SEPARATOR);
|
||||||
builder.append(data);
|
builder.append(data);
|
||||||
builder.append(VCARD_COL_SEPARATOR);
|
builder.append(VCARD_COL_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendVCardTelephoneLine(StringBuilder builder, Integer type, String label,
|
private void appendVCardTelephoneLine(final StringBuilder builder,
|
||||||
|
final Integer typeAsObject, final String label,
|
||||||
String encodedData) {
|
String encodedData) {
|
||||||
builder.append(VCARD_PROPERTY_TEL);
|
builder.append(VCARD_PROPERTY_TEL);
|
||||||
builder.append(VCARD_ATTR_SEPARATOR);
|
builder.append(VCARD_ATTR_SEPARATOR);
|
||||||
|
|
||||||
if (type == null) {
|
final int typeAsPrimitive;
|
||||||
type = Phone.TYPE_OTHER;
|
if (typeAsObject == null) {
|
||||||
|
typeAsPrimitive = Phone.TYPE_OTHER;
|
||||||
|
} else {
|
||||||
|
typeAsPrimitive = typeAsObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (typeAsPrimitive) {
|
||||||
case Phone.TYPE_HOME:
|
case Phone.TYPE_HOME:
|
||||||
appendTypeAttributes(builder, Arrays.asList(
|
appendTypeAttributes(builder, Arrays.asList(
|
||||||
Constants.ATTR_TYPE_HOME, Constants.ATTR_TYPE_VOICE));
|
Constants.ATTR_TYPE_HOME, Constants.ATTR_TYPE_VOICE));
|
||||||
@@ -1459,25 +1502,26 @@ public class VCardComposer {
|
|||||||
if (mIsDoCoMo) {
|
if (mIsDoCoMo) {
|
||||||
// Not sure about the reason, but previous implementation had
|
// Not sure about the reason, but previous implementation had
|
||||||
// used "VOICE" instead of "PAGER"
|
// used "VOICE" instead of "PAGER"
|
||||||
|
// Also, refrain from using appendType() so that "TYPE=" is never be appended.
|
||||||
builder.append(Constants.ATTR_TYPE_VOICE);
|
builder.append(Constants.ATTR_TYPE_VOICE);
|
||||||
} else {
|
} else {
|
||||||
builder.append(Constants.ATTR_TYPE_PAGER);
|
appendTypeAttribute(builder, Constants.ATTR_TYPE_PAGER);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Phone.TYPE_OTHER:
|
case Phone.TYPE_OTHER:
|
||||||
builder.append(Constants.ATTR_TYPE_VOICE);
|
appendTypeAttribute(builder, Constants.ATTR_TYPE_VOICE);
|
||||||
break;
|
break;
|
||||||
case Phone.TYPE_CUSTOM:
|
case Phone.TYPE_CUSTOM:
|
||||||
if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
|
if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
|
||||||
&& VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
|
&& VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
|
||||||
builder.append("X-" + label);
|
appendTypeAttribute(builder, "X-" + label);
|
||||||
} else {
|
} else {
|
||||||
// Just ignore the custom type.
|
// Just ignore the custom type.
|
||||||
builder.append(Constants.ATTR_TYPE_VOICE);
|
appendTypeAttribute(builder, Constants.ATTR_TYPE_VOICE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
appendUncommonPhoneType(builder, type);
|
appendUncommonPhoneType(builder, typeAsPrimitive);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1489,7 +1533,7 @@ public class VCardComposer {
|
|||||||
/**
|
/**
|
||||||
* Appends phone type string which may not be available in some devices.
|
* Appends phone type string which may not be available in some devices.
|
||||||
*/
|
*/
|
||||||
private void appendUncommonPhoneType(StringBuilder builder, Integer type) {
|
private void appendUncommonPhoneType(final StringBuilder builder, final Integer type) {
|
||||||
if (mIsDoCoMo) {
|
if (mIsDoCoMo) {
|
||||||
// The previous implementation for DoCoMo had been conservative
|
// The previous implementation for DoCoMo had been conservative
|
||||||
// about miscellaneous types.
|
// about miscellaneous types.
|
||||||
@@ -1497,7 +1541,7 @@ public class VCardComposer {
|
|||||||
} else {
|
} else {
|
||||||
String phoneAttribute = VCardUtils.getPhoneAttributeString(type);
|
String phoneAttribute = VCardUtils.getPhoneAttributeString(type);
|
||||||
if (phoneAttribute != null) {
|
if (phoneAttribute != null) {
|
||||||
builder.append(phoneAttribute);
|
appendTypeAttribute(builder, phoneAttribute);
|
||||||
} else {
|
} else {
|
||||||
Log.e(LOG_TAG, "Unknown or unsupported (by vCard) Phone type: " + type);
|
Log.e(LOG_TAG, "Unknown or unsupported (by vCard) Phone type: " + type);
|
||||||
}
|
}
|
||||||
@@ -1510,7 +1554,7 @@ public class VCardComposer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void appendVCardLine(final StringBuilder builder,
|
private void appendVCardLine(final StringBuilder builder,
|
||||||
final String field, final String rawData, boolean needCharset,
|
final String field, final String rawData, final boolean needCharset,
|
||||||
boolean needQuotedPrintable) {
|
boolean needQuotedPrintable) {
|
||||||
builder.append(field);
|
builder.append(field);
|
||||||
if (needCharset) {
|
if (needCharset) {
|
||||||
@@ -1545,11 +1589,11 @@ public class VCardComposer {
|
|||||||
} else {
|
} else {
|
||||||
builder.append(VCARD_ATTR_SEPARATOR);
|
builder.append(VCARD_ATTR_SEPARATOR);
|
||||||
}
|
}
|
||||||
appendType(builder, type);
|
appendTypeAttribute(builder, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendType(final StringBuilder builder, final String type) {
|
private void appendTypeAttribute(final StringBuilder builder, final String type) {
|
||||||
// Note: In vCard 3.0, Type strings also can be like this: "TYPE=HOME,PREF"
|
// Note: In vCard 3.0, Type strings also can be like this: "TYPE=HOME,PREF"
|
||||||
if (mIsV30) {
|
if (mIsV30) {
|
||||||
builder.append(Constants.ATTR_TYPE).append(VCARD_ATTR_EQUAL);
|
builder.append(Constants.ATTR_TYPE).append(VCARD_ATTR_EQUAL);
|
||||||
@@ -1581,7 +1625,7 @@ public class VCardComposer {
|
|||||||
str = tmpBuilder.toString();
|
str = tmpBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
final StringBuilder tmpBuilder = new StringBuilder();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
int lineCount = 0;
|
int lineCount = 0;
|
||||||
byte[] strArray = null;
|
byte[] strArray = null;
|
||||||
@@ -1594,7 +1638,7 @@ public class VCardComposer {
|
|||||||
strArray = str.getBytes();
|
strArray = str.getBytes();
|
||||||
}
|
}
|
||||||
while (index < strArray.length) {
|
while (index < strArray.length) {
|
||||||
builder.append(String.format("=%02X", strArray[index]));
|
tmpBuilder.append(String.format("=%02X", strArray[index]));
|
||||||
index += 1;
|
index += 1;
|
||||||
lineCount += 3;
|
lineCount += 3;
|
||||||
|
|
||||||
@@ -1606,11 +1650,11 @@ public class VCardComposer {
|
|||||||
// it will become
|
// it will become
|
||||||
// 6 bytes.
|
// 6 bytes.
|
||||||
// 76 - 6 - 3 = 67
|
// 76 - 6 - 3 = 67
|
||||||
builder.append("=\r\n");
|
tmpBuilder.append("=\r\n");
|
||||||
lineCount = 0;
|
lineCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.toString();
|
return tmpBuilder.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user