1198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa/* 2198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * Copyright (C) 2010 The Android Open Source Project 3198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * 4198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * use this file except in compliance with the License. You may obtain a copy of 6198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * the License at 7198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * 8198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * http://www.apache.org/licenses/LICENSE-2.0 9198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * 10198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * Unless required by applicable law or agreed to in writing, software 11198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * License for the specific language governing permissions and limitations under 14198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * the License. 15198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa */ 16198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawapackage com.android.bluetooth.pbap; 17198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 1800aee7a70e3c76b6c9ef59133d59fcdc592fea99Jaikumar Ganeshimport com.android.bluetooth.R; 1977ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvallimport com.android.internal.telephony.CallerInfo; 2000aee7a70e3c76b6c9ef59133d59fcdc592fea99Jaikumar Ganesh 21198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.content.ContentResolver; 22198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.content.Context; 23198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.database.Cursor; 24198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.database.sqlite.SQLiteException; 25198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.net.Uri; 26198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.provider.CallLog; 27198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.provider.CallLog.Calls; 28198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.text.TextUtils; 29198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.text.format.Time; 30198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.util.Log; 31198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 3212cb33f6d9fd269944a5618661e3880beea58b6eDaisuke Miyakawaimport com.android.vcard.VCardBuilder; 3312cb33f6d9fd269944a5618661e3880beea58b6eDaisuke Miyakawaimport com.android.vcard.VCardConfig; 3412cb33f6d9fd269944a5618661e3880beea58b6eDaisuke Miyakawaimport com.android.vcard.VCardConstants; 3512cb33f6d9fd269944a5618661e3880beea58b6eDaisuke Miyakawaimport com.android.vcard.VCardUtils; 3612cb33f6d9fd269944a5618661e3880beea58b6eDaisuke Miyakawa 37198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport java.util.Arrays; 38198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 39198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa/** 40198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * VCard composer especially for Call Log used in Bluetooth. 41198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa */ 42198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawapublic class BluetoothPbapCallLogComposer { 43198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final String TAG = "CallLogComposer"; 44198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 45198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final String FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO = 46198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa "Failed to get database information"; 47198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 48198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final String FAILURE_REASON_NO_ENTRY = 49198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa "There's no exportable in the database"; 50198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 51198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final String FAILURE_REASON_NOT_INITIALIZED = 52198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa "The vCard composer object is not correctly initialized"; 53198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 54198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa /** Should be visible only from developers... (no need to translate, hopefully) */ 55198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final String FAILURE_REASON_UNSUPPORTED_URI = 56198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa "The Uri vCard composer received is not supported by the composer."; 57198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 58198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final String NO_ERROR = "No error"; 59198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 60198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa /** The projection to use when querying the call log table */ 61198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final String[] sCallLogProjection = new String[] { 62198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa Calls.NUMBER, Calls.DATE, Calls.TYPE, Calls.CACHED_NAME, Calls.CACHED_NUMBER_TYPE, 63198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa Calls.CACHED_NUMBER_LABEL 64198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa }; 65198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final int NUMBER_COLUMN_INDEX = 0; 66198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final int DATE_COLUMN_INDEX = 1; 67198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final int CALL_TYPE_COLUMN_INDEX = 2; 68198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final int CALLER_NAME_COLUMN_INDEX = 3; 69198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final int CALLER_NUMBERTYPE_COLUMN_INDEX = 4; 70198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final int CALLER_NUMBERLABEL_COLUMN_INDEX = 5; 71198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 72198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa // Property for call log entry 73198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final String VCARD_PROPERTY_X_TIMESTAMP = "X-IRMC-CALL-DATETIME"; 740c21a35d6d56dd42c97a80e3233df578d0a1cb21David Yue private static final String VCARD_PROPERTY_CALLTYPE_INCOMING = "RECEIVED"; 750c21a35d6d56dd42c97a80e3233df578d0a1cb21David Yue private static final String VCARD_PROPERTY_CALLTYPE_OUTGOING = "DIALED"; 76198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private static final String VCARD_PROPERTY_CALLTYPE_MISSED = "MISSED"; 77198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 78198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private final Context mContext; 79198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private ContentResolver mContentResolver; 80198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private Cursor mCursor; 81198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 82198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private boolean mTerminateIsCalled; 83198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 84198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private String mErrorReason = NO_ERROR; 85198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 863c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa public BluetoothPbapCallLogComposer(final Context context) { 87198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa mContext = context; 88198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa mContentResolver = context.getContentResolver(); 89198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 90198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 91198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa public boolean init(final Uri contentUri, final String selection, 92198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa final String[] selectionArgs, final String sortOrder) { 93198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa final String[] projection; 94198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (CallLog.Calls.CONTENT_URI.equals(contentUri)) { 95198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa projection = sCallLogProjection; 96198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } else { 97198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa mErrorReason = FAILURE_REASON_UNSUPPORTED_URI; 98198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return false; 99198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 100198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 101198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa mCursor = mContentResolver.query( 102198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa contentUri, projection, selection, selectionArgs, sortOrder); 103198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 104198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (mCursor == null) { 105198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa mErrorReason = FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO; 106198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return false; 107198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 108198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 109198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (mCursor.getCount() == 0 || !mCursor.moveToFirst()) { 110198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa try { 111198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa mCursor.close(); 112198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } catch (SQLiteException e) { 113198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa Log.e(TAG, "SQLiteException on Cursor#close(): " + e.getMessage()); 114198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } finally { 115198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa mErrorReason = FAILURE_REASON_NO_ENTRY; 116198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa mCursor = null; 117198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 118198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return false; 119198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 120198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 121198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return true; 122198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 123198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 12473adcc0f5b6051ef514a3f16a2e28eabee2b367eConley Owens public String createOneEntry(boolean vcardVer21) { 125198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (mCursor == null || mCursor.isAfterLast()) { 126198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa mErrorReason = FAILURE_REASON_NOT_INITIALIZED; 1273c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa return null; 128198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 129198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa try { 13073adcc0f5b6051ef514a3f16a2e28eabee2b367eConley Owens return createOneCallLogEntryInternal(vcardVer21); 131b7533e86bb84a2f95c2cff62c1565a8e1696d1eaDavid Yue } finally { 132b7533e86bb84a2f95c2cff62c1565a8e1696d1eaDavid Yue mCursor.moveToNext(); 133198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 134198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 135198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 1369935a310a4f36c9f835c5c3aa2f604ddc36cabb1Xiaodong Xu private String createOneCallLogEntryInternal(boolean vcardVer21) { 1379935a310a4f36c9f835c5c3aa2f604ddc36cabb1Xiaodong Xu final int vcardType = (vcardVer21 ? VCardConfig.VCARD_TYPE_V21_GENERIC : 1389935a310a4f36c9f835c5c3aa2f604ddc36cabb1Xiaodong Xu VCardConfig.VCARD_TYPE_V30_GENERIC) | 139f7df7a88230c525e2973ca5603f54a77fe47445dJaikumar Ganesh VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING; 140f7df7a88230c525e2973ca5603f54a77fe47445dJaikumar Ganesh final VCardBuilder builder = new VCardBuilder(vcardType); 141198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa String name = mCursor.getString(CALLER_NAME_COLUMN_INDEX); 142198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (TextUtils.isEmpty(name)) { 14377ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall name = ""; 14477ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall } 14577ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall if (CallerInfo.UNKNOWN_NUMBER.equals(name) || CallerInfo.PRIVATE_NUMBER.equals(name) || 14677ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall CallerInfo.PAYPHONE_NUMBER.equals(name)) { 14777ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall // setting name to "" as FN/N must be empty fields in this case. 14877ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall name = ""; 149198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 150198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa final boolean needCharset = !(VCardUtils.containsOnlyPrintableAscii(name)); 151198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa builder.appendLine(VCardConstants.PROPERTY_FN, name, needCharset, false); 152198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa builder.appendLine(VCardConstants.PROPERTY_N, name, needCharset, false); 153198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 15400aee7a70e3c76b6c9ef59133d59fcdc592fea99Jaikumar Ganesh String number = mCursor.getString(NUMBER_COLUMN_INDEX); 15577ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall if (CallerInfo.UNKNOWN_NUMBER.equals(number) || 15677ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall CallerInfo.PRIVATE_NUMBER.equals(number) || 15777ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall CallerInfo.PAYPHONE_NUMBER.equals(number)) { 1582f429e31a13f81c9248173b144efca32c0070045Jaikumar Ganesh number = mContext.getString(R.string.unknownNumber); 15900aee7a70e3c76b6c9ef59133d59fcdc592fea99Jaikumar Ganesh } 160198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa final int type = mCursor.getInt(CALLER_NUMBERTYPE_COLUMN_INDEX); 161198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa String label = mCursor.getString(CALLER_NUMBERLABEL_COLUMN_INDEX); 162198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (TextUtils.isEmpty(label)) { 163198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa label = Integer.toString(type); 164198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 165198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa builder.appendTelLine(type, label, number, false); 166198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa tryAppendCallHistoryTimeStampField(builder); 167198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 168198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return builder.toString(); 169198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 170198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 171198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa /** 172198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * This static function is to compose vCard for phone own number 173198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa */ 174198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa public String composeVCardForPhoneOwnNumber(int phonetype, String phoneName, 175198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa String phoneNumber, boolean vcardVer21) { 176198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa final int vcardType = (vcardVer21 ? 177e05d3a710c592db386b55a265a1e657b0467e49fDaisuke Miyakawa VCardConfig.VCARD_TYPE_V21_GENERIC : 178f7df7a88230c525e2973ca5603f54a77fe47445dJaikumar Ganesh VCardConfig.VCARD_TYPE_V30_GENERIC) | 179f7df7a88230c525e2973ca5603f54a77fe47445dJaikumar Ganesh VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING; 180198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa final VCardBuilder builder = new VCardBuilder(vcardType); 181198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa boolean needCharset = false; 182198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (!(VCardUtils.containsOnlyPrintableAscii(phoneName))) { 183198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa needCharset = true; 184198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 185198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa builder.appendLine(VCardConstants.PROPERTY_FN, phoneName, needCharset, false); 186198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa builder.appendLine(VCardConstants.PROPERTY_N, phoneName, needCharset, false); 187198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 188198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (!TextUtils.isEmpty(phoneNumber)) { 189198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa String label = Integer.toString(phonetype); 190198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa builder.appendTelLine(phonetype, label, phoneNumber, false); 191198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 192198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 193198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return builder.toString(); 194198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 195198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 196198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa /** 197198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * Format according to RFC 2445 DATETIME type. 1981f18480dfa9ea5557bcd5928a4c152ab40b85c7eHåkan * The format is: ("%Y%m%dT%H%M%S"). 199198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa */ 200198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private final String toRfc2455Format(final long millSecs) { 201198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa Time startDate = new Time(); 202198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa startDate.set(millSecs); 2031f18480dfa9ea5557bcd5928a4c152ab40b85c7eHåkan return startDate.format2445(); 204198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 205198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 206198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa /** 207198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * Try to append the property line for a call history time stamp field if possible. 208198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa * Do nothing if the call log type gotton from the database is invalid. 209198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa */ 210198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa private void tryAppendCallHistoryTimeStampField(final VCardBuilder builder) { 211198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa // Extension for call history as defined in 212198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa // in the Specification for Ic Mobile Communcation - ver 1.1, 213198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa // Oct 2000. This is used to send the details of the call 214198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa // history - missed, incoming, outgoing along with date and time 215198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa // to the requesting device (For example, transferring phone book 216198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa // when connected over bluetooth) 217198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa // 2181f18480dfa9ea5557bcd5928a4c152ab40b85c7eHåkan // e.g. "X-IRMC-CALL-DATETIME;MISSED:20050320T100000" 219198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa final int callLogType = mCursor.getInt(CALL_TYPE_COLUMN_INDEX); 220198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa final String callLogTypeStr; 221198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa switch (callLogType) { 222198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa case Calls.INCOMING_TYPE: { 223198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa callLogTypeStr = VCARD_PROPERTY_CALLTYPE_INCOMING; 224198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa break; 225198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 226198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa case Calls.OUTGOING_TYPE: { 227198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa callLogTypeStr = VCARD_PROPERTY_CALLTYPE_OUTGOING; 228198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa break; 229198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 230198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa case Calls.MISSED_TYPE: { 231198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa callLogTypeStr = VCARD_PROPERTY_CALLTYPE_MISSED; 232198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa break; 233198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 234198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa default: { 235198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa Log.w(TAG, "Call log type not correct."); 236198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return; 237198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 238198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 239198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 240198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa final long dateAsLong = mCursor.getLong(DATE_COLUMN_INDEX); 241198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa builder.appendLine(VCARD_PROPERTY_X_TIMESTAMP, 242198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa Arrays.asList(callLogTypeStr), toRfc2455Format(dateAsLong)); 243198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 244198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 245198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa public void terminate() { 246198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (mCursor != null) { 247198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa try { 248198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa mCursor.close(); 249198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } catch (SQLiteException e) { 250198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa Log.e(TAG, "SQLiteException on Cursor#close(): " + e.getMessage()); 251198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 252198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa mCursor = null; 253198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 254198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 255198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa mTerminateIsCalled = true; 256198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 257198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 258198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa @Override 259198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa public void finalize() { 260198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (!mTerminateIsCalled) { 261198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa terminate(); 262198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 263198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 264198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 265198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa public int getCount() { 266198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (mCursor == null) { 267198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return 0; 268198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 269198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return mCursor.getCount(); 270198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 271198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 272198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa public boolean isAfterLast() { 273198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (mCursor == null) { 274198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return false; 275198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 276198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return mCursor.isAfterLast(); 277198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 278198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 279198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa public String getErrorReason() { 280198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return mErrorReason; 281198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 282198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa} 283