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:
Lixin Yue
2009-09-24 12:23:42 -07:00
committed by Android Git Automerger

View File

@@ -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;
@@ -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;
@@ -276,6 +284,25 @@ public class VCardComposer {
// 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);