am bfe1297b: Merge change 26869 into eclair
Merge commit 'bfe1297b12b1a81203dbd42ebbca7ff1916f1db7' into eclair-plus-aosp * commit 'bfe1297b12b1a81203dbd42ebbca7ff1916f1db7': Add call log support to pim.vcard.VCardComposer
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2009 The Android Open Source Project
|
* Copyright (C) 2009 The Android Open Source Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
* use this file except in compliance with the License. You may obtain a copy of
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
* the License at
|
* the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
@@ -38,6 +38,10 @@ 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.util.CharsetUtils;
|
import android.util.CharsetUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -61,11 +65,11 @@ import java.util.Map;
|
|||||||
* completely differnt implementation from
|
* completely differnt implementation from
|
||||||
* android.syncml.pim.vcard.VCardComposer, which is not maintained anymore.
|
* android.syncml.pim.vcard.VCardComposer, which is not maintained anymore.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Usually, this class should be used like this.
|
* Usually, this class should be used like this.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre class="prettyprint"> VCardComposer composer = null; try { composer = new
|
* <pre class="prettyprint"> VCardComposer composer = null; try { composer = new
|
||||||
* VCardComposer(context); composer.addHandler(composer.new
|
* VCardComposer(context); composer.addHandler(composer.new
|
||||||
* HandlerForOutputStream(outputStream)); if (!composer.init()) { // Do
|
* HandlerForOutputStream(outputStream)); if (!composer.init()) { // Do
|
||||||
@@ -213,6 +217,9 @@ public class VCardComposer {
|
|||||||
private static final String VCARD_PROPERTY_X_NICKNAME = "X-NICKNAME";
|
private static final String VCARD_PROPERTY_X_NICKNAME = "X-NICKNAME";
|
||||||
// TODO: add properties like X-LATITUDE
|
// TODO: add properties like X-LATITUDE
|
||||||
|
|
||||||
|
// Property for call log entry
|
||||||
|
private static final String VCARD_PROPERTY_X_TIMESTAMP = "X-IRMC-CALL-DATETIME";
|
||||||
|
|
||||||
// Properties for DoCoMo vCard.
|
// Properties for DoCoMo vCard.
|
||||||
private static final String VCARD_PROPERTY_X_CLASS = "X-CLASS";
|
private static final String VCARD_PROPERTY_X_CLASS = "X-CLASS";
|
||||||
private static final String VCARD_PROPERTY_X_REDUCTION = "X-REDUCTION";
|
private static final String VCARD_PROPERTY_X_REDUCTION = "X-REDUCTION";
|
||||||
@@ -227,6 +234,7 @@ public class VCardComposer {
|
|||||||
private static final String VCARD_DATA_SEPARATOR = ":";
|
private static final String VCARD_DATA_SEPARATOR = ":";
|
||||||
private static final String VCARD_ITEM_SEPARATOR = ";";
|
private static final String VCARD_ITEM_SEPARATOR = ";";
|
||||||
private static final String VCARD_WS = " ";
|
private static final String VCARD_WS = " ";
|
||||||
|
private static final String VCARD_ATTR_EQUAL = "=";
|
||||||
|
|
||||||
// Type strings are now in VCardConstants.java.
|
// Type strings are now in VCardConstants.java.
|
||||||
|
|
||||||
@@ -238,20 +246,20 @@ public class VCardComposer {
|
|||||||
private static final String SHIFT_JIS = "SHIFT_JIS";
|
private static final String SHIFT_JIS = "SHIFT_JIS";
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final int mVCardType;
|
private int mVCardType;
|
||||||
private final boolean mCareHandlerErrors;
|
private boolean mCareHandlerErrors;
|
||||||
private final ContentResolver mContentResolver;
|
private ContentResolver mContentResolver;
|
||||||
|
|
||||||
// Convenient member variables about the restriction of the vCard format.
|
// Convenient member variables about the restriction of the vCard format.
|
||||||
// Used for not calling the same methods returning same results.
|
// Used for not calling the same methods returning same results.
|
||||||
private final boolean mIsV30;
|
private boolean mIsV30;
|
||||||
private final boolean mIsJapaneseMobilePhone;
|
private boolean mIsJapaneseMobilePhone;
|
||||||
private final boolean mOnlyOneNoteFieldIsAvailable;
|
private boolean mOnlyOneNoteFieldIsAvailable;
|
||||||
private final boolean mIsDoCoMo;
|
private boolean mIsDoCoMo;
|
||||||
private final boolean mUsesQuotedPrintable;
|
private boolean mUsesQuotedPrintable;
|
||||||
private final boolean mUsesAndroidProperty;
|
private boolean mUsesAndroidProperty;
|
||||||
private final boolean mUsesDefactProperty;
|
private boolean mUsesDefactProperty;
|
||||||
private final boolean mUsesShiftJis;
|
private boolean mUsesShiftJis;
|
||||||
|
|
||||||
private Cursor mCursor;
|
private Cursor mCursor;
|
||||||
private int mIdColumn;
|
private int mIdColumn;
|
||||||
@@ -264,7 +272,7 @@ public class VCardComposer {
|
|||||||
private String mErrorReason = "No error";
|
private String mErrorReason = "No error";
|
||||||
|
|
||||||
private static final Map<Integer, String> sImMap;
|
private static final Map<Integer, String> sImMap;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
sImMap = new HashMap<Integer, String>();
|
sImMap = new HashMap<Integer, String>();
|
||||||
sImMap.put(Im.PROTOCOL_AIM, Constants.PROPERTY_X_AIM);
|
sImMap.put(Im.PROTOCOL_AIM, Constants.PROPERTY_X_AIM);
|
||||||
@@ -275,8 +283,27 @@ public class VCardComposer {
|
|||||||
sImMap.put(Im.PROTOCOL_SKYPE, Constants.PROPERTY_X_SKYPE_USERNAME);
|
sImMap.put(Im.PROTOCOL_SKYPE, Constants.PROPERTY_X_SKYPE_USERNAME);
|
||||||
// Google talk is a special case.
|
// Google talk is a special case.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean mIsCallLogComposer = false;
|
||||||
|
|
||||||
|
private static final String[] CONTACTS_PROJECTION = new String[] {
|
||||||
|
Contacts._ID,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** The projection to use when querying the call log table */
|
||||||
|
private static final String[] CALL_LOG_PROJECTION = new String[] {
|
||||||
|
Calls.NUMBER, Calls.DATE, Calls.TYPE, Calls.CACHED_NAME, Calls.CACHED_NUMBER_TYPE,
|
||||||
|
Calls.CACHED_NUMBER_LABEL
|
||||||
|
};
|
||||||
|
private static final int NUMBER_COLUMN_INDEX = 0;
|
||||||
|
private static final int DATE_COLUMN_INDEX = 1;
|
||||||
|
private static final int CALL_TYPE_COLUMN_INDEX = 2;
|
||||||
|
private static final int CALLER_NAME_COLUMN_INDEX = 3;
|
||||||
|
private static final int CALLER_NUMBERTYPE_COLUMN_INDEX = 4;
|
||||||
|
private static final int CALLER_NUMBERLABEL_COLUMN_INDEX = 5;
|
||||||
|
|
||||||
|
private static final String FLAG_TIMEZONE_UTC = "Z";
|
||||||
|
|
||||||
public VCardComposer(Context context) {
|
public VCardComposer(Context context) {
|
||||||
this(context, VCardConfig.VCARD_TYPE_DEFAULT, true);
|
this(context, VCardConfig.VCARD_TYPE_DEFAULT, true);
|
||||||
}
|
}
|
||||||
@@ -287,10 +314,15 @@ public class VCardComposer {
|
|||||||
careHandlerErrors);
|
careHandlerErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VCardComposer(Context context, int vcardType, boolean careHandlerErrors) {
|
/**
|
||||||
|
* Construct for supporting call log entry vCard composing
|
||||||
|
*/
|
||||||
|
public VCardComposer(Context context, int vcardType, boolean careHandlerErrors,
|
||||||
|
boolean isCallLogComposer) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mVCardType = vcardType;
|
mVCardType = vcardType;
|
||||||
mCareHandlerErrors = careHandlerErrors;
|
mCareHandlerErrors = careHandlerErrors;
|
||||||
|
mIsCallLogComposer = isCallLogComposer;
|
||||||
mContentResolver = context.getContentResolver();
|
mContentResolver = context.getContentResolver();
|
||||||
|
|
||||||
mIsV30 = VCardConfig.isV30(vcardType);
|
mIsV30 = VCardConfig.isV30(vcardType);
|
||||||
@@ -320,6 +352,38 @@ public class VCardComposer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VCardComposer(Context context, int vcardType, boolean careHandlerErrors) {
|
||||||
|
this(context, vcardType, careHandlerErrors, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This static function is to compose vCard for phone own number
|
||||||
|
*/
|
||||||
|
public String composeVCardForPhoneOwnNumber(int phonetype, String phoneName,
|
||||||
|
String phoneNumber, boolean vcardVer21) {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
appendVCardLine(builder, VCARD_PROPERTY_BEGIN, VCARD_DATA_VCARD);
|
||||||
|
if (!vcardVer21) {
|
||||||
|
appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V30);
|
||||||
|
} else {
|
||||||
|
appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V21);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean needCharset = false;
|
||||||
|
if (!(VCardUtils.containsOnlyAscii(phoneName))) {
|
||||||
|
needCharset = true;
|
||||||
|
}
|
||||||
|
appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, phoneName, needCharset, false);
|
||||||
|
appendVCardLine(builder, VCARD_PROPERTY_NAME, phoneName, needCharset, false);
|
||||||
|
|
||||||
|
String label = Integer.toString(phonetype);
|
||||||
|
appendVCardTelephoneLine(builder, phonetype, label, phoneNumber);
|
||||||
|
|
||||||
|
appendVCardLine(builder, VCARD_PROPERTY_END, VCARD_DATA_VCARD);
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must call before {{@link #init()}.
|
* Must call before {{@link #init()}.
|
||||||
*/
|
*/
|
||||||
@@ -357,11 +421,15 @@ public class VCardComposer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final String[] projection = new String[] {Contacts._ID,};
|
if (mIsCallLogComposer) {
|
||||||
|
mCursor = mContentResolver.query(CallLog.Calls.CONTENT_URI, CALL_LOG_PROJECTION,
|
||||||
|
selection, selectionArgs, null);
|
||||||
|
} else {
|
||||||
|
// TODO: thorow an appropriate exception!
|
||||||
|
mCursor = mContentResolver.query(RawContacts.CONTENT_URI, CONTACTS_PROJECTION,
|
||||||
|
selection, selectionArgs, null);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: thorow an appropriate exception!
|
|
||||||
mCursor = mContentResolver.query(RawContacts.CONTENT_URI, projection,
|
|
||||||
selection, selectionArgs, null);
|
|
||||||
if (mCursor == null || !mCursor.moveToFirst()) {
|
if (mCursor == null || !mCursor.moveToFirst()) {
|
||||||
if (mCursor != null) {
|
if (mCursor != null) {
|
||||||
try {
|
try {
|
||||||
@@ -376,7 +444,11 @@ public class VCardComposer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mIdColumn = mCursor.getColumnIndex(Contacts._ID);
|
if (mIsCallLogComposer) {
|
||||||
|
mIdColumn = -1;
|
||||||
|
} else {
|
||||||
|
mIdColumn = mCursor.getColumnIndex(Contacts._ID);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -390,7 +462,16 @@ public class VCardComposer {
|
|||||||
String name = null;
|
String name = null;
|
||||||
String vcard;
|
String vcard;
|
||||||
try {
|
try {
|
||||||
vcard = createOneEntryInternal(mCursor.getString(mIdColumn));
|
if (mIsCallLogComposer) {
|
||||||
|
vcard = createOneCallLogEntryInternal();
|
||||||
|
} else {
|
||||||
|
if (mIdColumn >= 0) {
|
||||||
|
vcard = createOneEntryInternal(mCursor.getString(mIdColumn));
|
||||||
|
} else {
|
||||||
|
Log.e(LOG_TAG, "Incorrect mIdColumn: " + mIdColumn);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (OutOfMemoryError error) {
|
} catch (OutOfMemoryError error) {
|
||||||
// Maybe some data (e.g. photo) is too big to have in memory. But it
|
// Maybe some data (e.g. photo) is too big to have in memory. But it
|
||||||
// should be rare.
|
// should be rare.
|
||||||
@@ -422,6 +503,89 @@ public class VCardComposer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format according to RFC 2445 DATETIME type.
|
||||||
|
* The format is: ("%Y%m%dT%H%M%S").
|
||||||
|
*/
|
||||||
|
private final String formatDate(final long millSecs) {
|
||||||
|
Time startDate = new Time();
|
||||||
|
startDate.set(millSecs);
|
||||||
|
String date = startDate.format2445();
|
||||||
|
return date + FLAG_TIMEZONE_UTC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create call history time stamp field.
|
||||||
|
*
|
||||||
|
* @param type call type
|
||||||
|
*/
|
||||||
|
private String createCallHistoryTimeStampField(int type) {
|
||||||
|
// Extension for call history as defined in
|
||||||
|
// in the Specification for Ic Mobile Communcation - ver 1.1,
|
||||||
|
// Oct 2000. This is used to send the details of the call
|
||||||
|
// history - missed, incoming, outgoing along with date and time
|
||||||
|
// to the requesting device (For example, transferring phone book
|
||||||
|
// when connected over bluetooth)
|
||||||
|
// X-IRMC-CALL-DATETIME;MISSED:20050320T100000
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append(VCARD_PROPERTY_X_TIMESTAMP);
|
||||||
|
builder.append(VCARD_ATTR_SEPARATOR);
|
||||||
|
|
||||||
|
if (mIsV30) {
|
||||||
|
builder.append(Constants.ATTR_TYPE).append(VCARD_ATTR_EQUAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == Calls.INCOMING_TYPE) {
|
||||||
|
builder.append("INCOMING");
|
||||||
|
} else if (type == Calls.OUTGOING_TYPE) {
|
||||||
|
builder.append("OUTGOING");
|
||||||
|
} else if (type == Calls.MISSED_TYPE) {
|
||||||
|
builder.append("MISSED");
|
||||||
|
} else {
|
||||||
|
Log.w(LOG_TAG, "Call log type not correct.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createOneCallLogEntryInternal() {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
appendVCardLine(builder, VCARD_PROPERTY_BEGIN, VCARD_DATA_VCARD);
|
||||||
|
if (mIsV30) {
|
||||||
|
appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V30);
|
||||||
|
} else {
|
||||||
|
appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V21);
|
||||||
|
}
|
||||||
|
String name = mCursor.getString(CALLER_NAME_COLUMN_INDEX);
|
||||||
|
if (TextUtils.isEmpty(name)) {
|
||||||
|
name = mCursor.getString(NUMBER_COLUMN_INDEX);
|
||||||
|
}
|
||||||
|
boolean needCharset = !(VCardUtils.containsOnlyAscii(name));
|
||||||
|
appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, name, needCharset, false);
|
||||||
|
appendVCardLine(builder, VCARD_PROPERTY_NAME, name, needCharset, false);
|
||||||
|
|
||||||
|
String number = mCursor.getString(NUMBER_COLUMN_INDEX);
|
||||||
|
int type = mCursor.getInt(CALLER_NUMBERTYPE_COLUMN_INDEX);
|
||||||
|
String label = mCursor.getString(CALLER_NUMBERLABEL_COLUMN_INDEX);
|
||||||
|
if (TextUtils.isEmpty(label)) {
|
||||||
|
label = Integer.toString(type);
|
||||||
|
}
|
||||||
|
appendVCardTelephoneLine(builder, type, label, number);
|
||||||
|
|
||||||
|
long date = mCursor.getLong(DATE_COLUMN_INDEX);
|
||||||
|
String dateClause = formatDate(date);
|
||||||
|
int callLogType = mCursor.getInt(CALL_TYPE_COLUMN_INDEX);
|
||||||
|
String timestampFeldString = createCallHistoryTimeStampField(callLogType);
|
||||||
|
if (timestampFeldString != null) {
|
||||||
|
appendVCardLine(builder, timestampFeldString, dateClause);
|
||||||
|
}
|
||||||
|
|
||||||
|
appendVCardLine(builder, VCARD_PROPERTY_END, VCARD_DATA_VCARD);
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
private String createOneEntryInternal(final String contactId) {
|
private String createOneEntryInternal(final String contactId) {
|
||||||
final StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
appendVCardLine(builder, VCARD_PROPERTY_BEGIN, VCARD_DATA_VCARD);
|
appendVCardLine(builder, VCARD_PROPERTY_BEGIN, VCARD_DATA_VCARD);
|
||||||
@@ -576,7 +740,7 @@ public class VCardComposer {
|
|||||||
final String encodedPrefix = escapeCharacters(prefix);
|
final String encodedPrefix = escapeCharacters(prefix);
|
||||||
final String encodedSuffix = escapeCharacters(suffix);
|
final String encodedSuffix = escapeCharacters(suffix);
|
||||||
|
|
||||||
// N property. This order is specified by vCard spec and does not depend on countries.
|
// N property. This order is specified by vCard spec and does not depend on countries.
|
||||||
builder.append(VCARD_PROPERTY_NAME);
|
builder.append(VCARD_PROPERTY_NAME);
|
||||||
if (!(VCardUtils.containsOnlyAscii(familyName) &&
|
if (!(VCardUtils.containsOnlyAscii(familyName) &&
|
||||||
VCardUtils.containsOnlyAscii(givenName) &&
|
VCardUtils.containsOnlyAscii(givenName) &&
|
||||||
@@ -584,7 +748,7 @@ public class VCardComposer {
|
|||||||
VCardUtils.containsOnlyAscii(prefix) &&
|
VCardUtils.containsOnlyAscii(prefix) &&
|
||||||
VCardUtils.containsOnlyAscii(suffix))) {
|
VCardUtils.containsOnlyAscii(suffix))) {
|
||||||
builder.append(VCARD_ATTR_SEPARATOR);
|
builder.append(VCARD_ATTR_SEPARATOR);
|
||||||
builder.append(mVCardAttributeCharset);
|
builder.append(mVCardAttributeCharset);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.append(VCARD_DATA_SEPARATOR);
|
builder.append(VCARD_DATA_SEPARATOR);
|
||||||
@@ -658,7 +822,7 @@ public class VCardComposer {
|
|||||||
// but we'll add this info since parser side may be able to
|
// but we'll add this info since parser side may be able to
|
||||||
// use the charset via
|
// use the charset via
|
||||||
// this attribute field.
|
// this attribute field.
|
||||||
//
|
//
|
||||||
// e.g. Japanese mobile phones use Shift_Jis while RFC 2426
|
// e.g. Japanese mobile phones use Shift_Jis while RFC 2426
|
||||||
// recommends
|
// recommends
|
||||||
// UTF-8. By adding this field, parsers may be able to know
|
// UTF-8. By adding this field, parsers may be able to know
|
||||||
@@ -684,12 +848,12 @@ public class VCardComposer {
|
|||||||
builder.append(VCARD_ATTR_SEPARATOR);
|
builder.append(VCARD_ATTR_SEPARATOR);
|
||||||
builder.append(Constants.ATTR_TYPE_X_IRMC_N);
|
builder.append(Constants.ATTR_TYPE_X_IRMC_N);
|
||||||
builder.append(VCARD_ATTR_SEPARATOR);
|
builder.append(VCARD_ATTR_SEPARATOR);
|
||||||
|
|
||||||
if (!(VCardUtils.containsOnlyAscii(phoneticFamilyName) &&
|
if (!(VCardUtils.containsOnlyAscii(phoneticFamilyName) &&
|
||||||
VCardUtils.containsOnlyAscii(phoneticMiddleName) &&
|
VCardUtils.containsOnlyAscii(phoneticMiddleName) &&
|
||||||
VCardUtils.containsOnlyAscii(phoneticGivenName))) {
|
VCardUtils.containsOnlyAscii(phoneticGivenName))) {
|
||||||
builder.append(mVCardAttributeCharset);
|
builder.append(mVCardAttributeCharset);
|
||||||
builder.append(VCARD_DATA_SEPARATOR);
|
builder.append(VCARD_DATA_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.append(escapeCharacters(phoneticFamilyName));
|
builder.append(escapeCharacters(phoneticFamilyName));
|
||||||
@@ -841,7 +1005,7 @@ public class VCardComposer {
|
|||||||
builder.append(VCARD_COL_SEPARATOR);
|
builder.append(VCARD_COL_SEPARATOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to append just one line. If there's no appropriate address
|
* Try to append just one line. If there's no appropriate address
|
||||||
* information, append an empty line.
|
* information, append an empty line.
|
||||||
@@ -907,10 +1071,10 @@ public class VCardComposer {
|
|||||||
}
|
}
|
||||||
// TODO: add "X-GOOGLE TALK" case...
|
// TODO: add "X-GOOGLE TALK" case...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
List<ContentValues> contentValuesList = contentValuesListMap
|
||||||
@@ -922,7 +1086,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
|
List<ContentValues> contentValuesList = contentValuesListMap
|
||||||
@@ -1029,7 +1193,7 @@ public class VCardComposer {
|
|||||||
/**
|
/**
|
||||||
* Append '\' to the characters which should be escaped. The character set is different
|
* 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.
|
* not only between vCard 2.1 and vCard 3.0 but also among each device.
|
||||||
*
|
*
|
||||||
* Note that Quoted-Printable string must not be input here.
|
* Note that Quoted-Printable string must not be input here.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("fallthrough")
|
@SuppressWarnings("fallthrough")
|
||||||
@@ -1037,7 +1201,7 @@ public class VCardComposer {
|
|||||||
if (TextUtils.isEmpty(unescaped)) {
|
if (TextUtils.isEmpty(unescaped)) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = 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++) {
|
||||||
@@ -1358,7 +1522,7 @@ public class VCardComposer {
|
|||||||
encodedData = encodeQuotedPrintable(rawData);
|
encodedData = encodeQuotedPrintable(rawData);
|
||||||
} else {
|
} else {
|
||||||
// TODO: one line may be too huge, which may be invalid in vCard spec, though
|
// TODO: one line may be too huge, which may be invalid in vCard spec, though
|
||||||
// several (even well-known) applications do not care this.
|
// several (even well-known) applications do not care this.
|
||||||
encodedData = escapeCharacters(rawData);
|
encodedData = escapeCharacters(rawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user