diff options
author | kaiyiz <kaiyiz@codeaurora.org> | 2014-04-02 18:05:25 +0800 |
---|---|---|
committer | cretin45 <cretin45@gmail.com> | 2014-09-03 13:57:41 -0700 |
commit | 89bfb7fd91978ad2f2a5f1588472af68d010698b (patch) | |
tree | 8c9c538124816a1763bc34a7648e60b1507a986e | |
parent | 9485ed7d42341b00a427a678a183b37acacf21b2 (diff) | |
download | android_packages_providers_TelephonyProvider-89bfb7fd91978ad2f2a5f1588472af68d010698b.tar.gz android_packages_providers_TelephonyProvider-89bfb7fd91978ad2f2a5f1588472af68d010698b.tar.bz2 android_packages_providers_TelephonyProvider-89bfb7fd91978ad2f2a5f1588472af68d010698b.zip |
TelephonyProvider: Support classification search for message.
The Mms application does not support classify of search mode.
Create a new SearchActivityExtend Activity and add function of classify of
search mode in TelephonyProvider for Mms, to achieve extend search functon
by name, number and content.
CRs-Fixed: 637267
Change-Id: Ia4392380c9087bacf8a7ece780ea5ff957d920c7
-rw-r--r-- | src/com/android/providers/telephony/MmsSmsProvider.java | 297 |
1 files changed, 296 insertions, 1 deletions
diff --git a/src/com/android/providers/telephony/MmsSmsProvider.java b/src/com/android/providers/telephony/MmsSmsProvider.java index cf191c3..f12da15 100644 --- a/src/com/android/providers/telephony/MmsSmsProvider.java +++ b/src/com/android/providers/telephony/MmsSmsProvider.java @@ -95,8 +95,19 @@ public class MmsSmsProvider extends ContentProvider { private static final int URI_FIRST_LOCKED_MESSAGE_BY_THREAD_ID = 17; private static final int URI_MESSAGE_ID_TO_THREAD = 18; private static final int URI_MAILBOX_MESSAGES = 19; - private static final int URI_MAILBOXS = 21; + private static final int URI_SEARCH_MESSAGE = 20; + private static final int URI_MAILBOXS = 21; private static final int URI_MAILBOX_MESSAGES_COUNT = 22; + // Escape character + private static final char SEARCH_ESCAPE_CHARACTER = '!'; + + public static final int SEARCH_MODE_CONTENT = 0; + public static final int SEARCH_MODE_NAME = 1; + public static final int SEARCH_MODE_NUMBER = 2; + + // add for different match mode in classify search + public static final int MATCH_BY_ADDRESS = 0; + public static final int MATCH_BY_THREAD_ID = 1; /** * the name of the table that is used to store the queue of @@ -255,6 +266,39 @@ public class MmsSmsProvider extends ContentProvider { + "on messeagebox.boxtype = type " + "group by boxname order by _id"; + private static final String SMS_PROJECTION = "'sms' AS transport_type, _id, thread_id," + + "address, body, sub_id, date, date_sent, read, type," + + "status, locked, NULL AS error_code," + + "NULL AS sub, NULL AS sub_cs, date, date_sent, read," + + "NULL as m_type," + + "NULL AS msg_box," + + "NULL AS d_rpt, NULL AS rr, NULL AS err_type," + + "locked, NULL AS st, NULL AS text_only," + + "sub_id, NULL AS recipient_ids"; + + private static final String MMS_PROJECTION = "'mms' AS transport_type, pdu._id, thread_id," + + "addr.address AS address, part.text as body, sub_id," + + "pdu.date * 1000 AS date, date_sent, read, NULL AS type," + + "NULL AS status, locked, NULL AS error_code," + + "sub, sub_cs, date, date_sent, read," + + "m_type," + + "pdu.msg_box AS msg_box," + + "d_rpt, rr, NULL AS err_type," + + "locked, NULL AS st, NULL AS text_only," + + "sub_id, NULL AS recipient_ids"; + + private static final String MMS_PROJECTION_FOR_NUMBER_SEARCH = + "'mms' AS transport_type, pdu._id, thread_id," + + "addr.address AS address, NULL AS body, sub_id," + + "pdu.date * 1000 AS date, date_sent, read, NULL AS type," + + "NULL AS status, locked, NULL AS error_code," + + "sub, sub_cs, date, date_sent, read," + + "m_type," + + "pdu.msg_box AS msg_box," + + "d_rpt, rr, NULL AS err_type," + + "locked, NULL AS st, NULL AS text_only," + + "sub_id, NULL AS recipient_ids"; + private static final String AUTHORITY = "mms-sms"; static { @@ -283,6 +327,10 @@ public class MmsSmsProvider extends ContentProvider { // URI for deleting obsolete threads. URI_MATCHER.addURI(AUTHORITY, "conversations/obsolete", URI_OBSOLETE_THREADS); + // URI for search messages in mailbox mode with obtained search mode + // such as content, number and name + URI_MATCHER.addURI(AUTHORITY, "search-message", URI_SEARCH_MESSAGE); + URI_MATCHER.addURI( AUTHORITY, "messages/byphone/*", URI_MESSAGES_BY_PHONE); @@ -493,6 +541,9 @@ public class MmsSmsProvider extends ContentProvider { } break; } + case URI_SEARCH_MESSAGE: + cursor = getSearchMessages(uri, db); + break; case URI_PENDING_MSG: { String protoName = uri.getQueryParameter("protocol"); String msgId = uri.getQueryParameter("message"); @@ -1596,4 +1647,248 @@ public class MmsSmsProvider extends ContentProvider { UNION_COLUMNS[i++] = columnName; } } + + private Cursor getSearchMessages(Uri uri, SQLiteDatabase db) { + int searchMode = Integer.parseInt(uri.getQueryParameter("search_mode")); + String keyStr = uri.getQueryParameter("key_str"); + int matchWhole = Integer.parseInt(uri.getQueryParameter("match_whole")); + Log.d(LOG_TAG, "getSearchMessages : searchMode =" + searchMode + ",keyStr=" + + keyStr + ",matchWhole=" + matchWhole); + + String searchString = "%" + addEscapeCharacter(keyStr) + "%"; + String threadIdString = ""; + + if (matchWhole == MATCH_BY_THREAD_ID) { + threadIdString = getThreadIdString(keyStr); + } + + String smsMailBoxConstraints = ""; + String mmsMailBoxConstraints = ""; + String smsQuery = ""; + String mmsQuery = ""; + + if (searchMode == SEARCH_MODE_CONTENT) { + smsQuery = String.format( + "SELECT %s FROM sms WHERE (body LIKE ? ESCAPE '" + + SEARCH_ESCAPE_CHARACTER + "') ", + SMS_PROJECTION); + mmsQuery = String.format( + "SELECT %s FROM pdu,part,addr WHERE ((part.mid=pdu._id) AND " + + "(addr.msg_id=pdu._id) AND " + + "(addr.type=%d) AND " + + "(part.ct='text/plain') AND " + + "(body like ? escape '" + SEARCH_ESCAPE_CHARACTER + "')) GROUP BY pdu._id", + MMS_PROJECTION, + PduHeaders.TO); + } else if (searchMode == SEARCH_MODE_NUMBER && matchWhole == MATCH_BY_ADDRESS) { + smsQuery = String.format( + "SELECT %s FROM sms WHERE (address LIKE ?)", + SMS_PROJECTION); + mmsQuery = String.format( + "SELECT %s FROM pdu,addr WHERE (" + + "(addr.msg_id=pdu._id) AND " + + "(address like ?)) GROUP BY pdu._id", + MMS_PROJECTION_FOR_NUMBER_SEARCH); + } else if (searchMode == SEARCH_MODE_NUMBER && matchWhole == MATCH_BY_THREAD_ID) { + smsQuery = String.format( + "SELECT %s FROM sms WHERE (thread_id in (%s))", + SMS_PROJECTION, + threadIdString); + + mmsQuery = String.format( + "SELECT %s FROM pdu,addr WHERE (" + + "(thread_id in (%s)) AND " + + "(addr.msg_id = pdu._id) AND " + + "(addr.type=%d))", + MMS_PROJECTION_FOR_NUMBER_SEARCH, + threadIdString, + PduHeaders.TO); + } + + String rawQuery = String.format( + "%s UNION %s ORDER BY date DESC", + smsQuery, + mmsQuery); + String[] strArray; + if (searchMode == SEARCH_MODE_CONTENT + || (searchMode == SEARCH_MODE_NUMBER && matchWhole == MATCH_BY_ADDRESS)) { + strArray = new String[] { + searchString, searchString + }; + } else { + strArray = EMPTY_STRING_ARRAY; + } + return db.rawQuery(rawQuery, strArray); + } + + private String getThreadIdString(String keyStr) { + long[] addressIdSet = getSortedSet(getAddressIdsByAddressList(keyStr.split(","))); + String threadIdString = getCommaSeparatedId(addressIdSet); + if (TextUtils.isEmpty(threadIdString)) { + threadIdString = "0"; + } + return threadIdString; + } + + private String addEscapeCharacter(String keyStr) { + if (keyStr == null) { + return keyStr; + } + if (keyStr.contains("%") || + keyStr.contains(String.valueOf(SEARCH_ESCAPE_CHARACTER))) { + StringBuilder searchKeyStrBuilder = new StringBuilder(); + int keyStrLen = keyStr.length(); + for (int i = 0; i < keyStrLen; i++) { + if (keyStr.charAt(i) == '%' || + keyStr.charAt(i) == SEARCH_ESCAPE_CHARACTER) { + searchKeyStrBuilder.append(SEARCH_ESCAPE_CHARACTER); + searchKeyStrBuilder.append(keyStr.charAt(i)); + continue; + } + searchKeyStrBuilder.append(keyStr.charAt(i)); + } + return searchKeyStrBuilder.toString(); + } + return keyStr; + } + + private Set<Long> getAddressIdsByAddressList(String[] addresses) { + int count = addresses.length; + Set<Long> result = new HashSet<Long>(count); + + for (int i = 0; i < count; i++) { + String address = addresses[i]; + if (address != null && !address.equals(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) { + long id = getSingleThreadId(address); + if (id != -1L) { + result.add(id); + } else { + Log.e(LOG_TAG, "Address ID not found for: " + address); + } + } + } + return result; + } + + private String getCommaSeparatedId(long[] addrIds) { + int size = addrIds.length; + StringBuilder buffer = new StringBuilder(); + + for (int i = 0; i < size; i++) { + if (i != 0) { + buffer.append(','); + } + buffer.append(getThreadIds(String.valueOf(addrIds[i]))); + } + return buffer.toString(); + } + + private long getSingleThreadId(String address) { + boolean isEmail = Mms.isEmailAddress(address); + String refinedAddress = isEmail ? address.toLowerCase() : address; + String selection = "address=?"; + String[] selectionArgs; + + if (isEmail) { + selectionArgs = new String[] { refinedAddress }; + } else { + selection += " OR " + String.format("PHONE_NUMBERS_EQUAL(address, ?, %d)", + (mUseStrictPhoneNumberComparation ? 1 : 0)); + selectionArgs = new String[] { refinedAddress, refinedAddress }; + } + + Cursor cursor = null; + + try { + SQLiteDatabase db = mOpenHelper.getReadableDatabase(); + cursor = db.query( + "canonical_addresses", ID_PROJECTION, + selection, selectionArgs, null, null, null); + + if (cursor.getCount() == 0) { + return -1L; + } + + if (cursor.moveToFirst()) { + return cursor.getLong(cursor.getColumnIndexOrThrow(BaseColumns._ID)); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return -1L; + } + + private synchronized String getThreadIdByRecipientIds(String recipientIds) { + String THREAD_QUERY = "SELECT _id FROM threads " + + "WHERE recipient_ids = ?"; + String resultString = "0"; + + if (DEBUG) { + Log.v(LOG_TAG, "getThreadId THREAD_QUERY: " + THREAD_QUERY + + ", recipientIds=" + recipientIds); + } + Cursor cursor = null; + try { + SQLiteDatabase db = mOpenHelper.getReadableDatabase(); + cursor = db.rawQuery(THREAD_QUERY, new String[] { recipientIds }); + + if (cursor == null || cursor.getCount() == 0) { + return resultString; + } + + if (cursor.moveToFirst()) { + resultString = String.valueOf(cursor.getLong(0)); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return resultString; + } + + private synchronized String getThreadIds(String recipientIds) { + String THREAD_QUERY = "SELECT _id FROM threads " + + "WHERE recipient_ids = ? or recipient_ids like '" + recipientIds + + " %' or recipient_ids like '% " + recipientIds + + "' or recipient_ids like '% " + recipientIds + " %'"; + String resultString = "0"; + StringBuilder buffer = new StringBuilder(); + + if (DEBUG) { + Log.v(LOG_TAG, "getThreadId THREAD_QUERY: " + THREAD_QUERY + + ", recipientIds=" + recipientIds); + } + Cursor cursor = null; + try { + SQLiteDatabase db = mOpenHelper.getReadableDatabase(); + cursor = db.rawQuery(THREAD_QUERY, new String[] { + recipientIds + }); + + if (cursor == null || cursor.getCount() == 0) { + return resultString; + } + int i = 0; + while (cursor.moveToNext()) { + if (i != 0) { + buffer.append(','); + } + buffer.append(String.valueOf(cursor.getLong(0))); + i++; + } + resultString = buffer.toString(); + + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return resultString; + } } |