summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaiyiz <kaiyiz@codeaurora.org>2014-04-02 18:05:25 +0800
committercretin45 <cretin45@gmail.com>2014-09-03 13:57:41 -0700
commit89bfb7fd91978ad2f2a5f1588472af68d010698b (patch)
tree8c9c538124816a1763bc34a7648e60b1507a986e
parent9485ed7d42341b00a427a678a183b37acacf21b2 (diff)
downloadandroid_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.java297
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;
+ }
}