MmsSmsProviderpublic class MmsSmsProvider extends android.content.ContentProvider This class provides the ability to query the MMS and SMS databases
at the same time, mixing messages from both in a single thread
(A.K.A. conversation).
A virtual column, MmsSms.TYPE_DISCRIMINATOR_COLUMN, may be
requested in the projection for a query. Its value is either "mms"
or "sms", depending on whether the message represented by the row
is an MMS message or an SMS message, respectively.
This class also provides the ability to find out what addresses
participated in a particular thread. It doesn't support updates
for either of these.
This class provides a way to allocate and retrieve thread IDs.
This is done atomically through a query. There is no insert URI
for this.
Finally, this class provides a way to delete or update all messages
in a thread. |
Fields Summary |
---|
private static final android.content.UriMatcher | URI_MATCHER | private static final String | LOG_TAG | private static final String | NO_DELETES_INSERTS_OR_UPDATES | private static final int | URI_CONVERSATIONS | private static final int | URI_CONVERSATIONS_MESSAGES | private static final int | URI_CONVERSATIONS_RECIPIENTS | private static final int | URI_MESSAGES_BY_PHONE | private static final int | URI_THREAD_ID | private static final int | URI_CANONICAL_ADDRESS | private static final int | URI_PENDING_MSG | private static final int | URI_COMPLETE_CONVERSATIONS | private static final int | URI_UNDELIVERED_MSG | private static final int | URI_CONVERSATIONS_SUBJECT | private static final int | URI_NOTIFICATIONS | private static final int | URI_OBSOLETE_THREADS | private static final int | URI_DRAFT | public static final String | TABLE_PENDING_MSGthe name of the table that is used to store the queue of
messages(both MMS and SMS) to be sent/downloaded. | private static final String[] | MMS_SMS_COLUMNS | private static final String[] | MMS_ONLY_COLUMNS | private static final String[] | SMS_ONLY_COLUMNS | private static final String[] | THREADS_COLUMNS | private static final String[] | UNION_COLUMNS | private static final Set | MMS_COLUMNS | private static final Set | SMS_COLUMNS | private static final String | VND_ANDROID_DIR_MMS_SMS | private static final String[] | ID_PROJECTION | private static final String[] | EMPTY_STRING_ARRAY | private static final String | SMS_CONVERSATION_CONSTRAINT | private static final String | MMS_CONVERSATION_CONSTRAINT | private static final String | AUTHORITY | private android.database.sqlite.SQLiteOpenHelper | mOpenHelper |
Methods Summary |
---|
private static java.lang.String | buildConversationQuery(java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)
String[] mmsProjection = createMmsProjection(projection);
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
mmsQueryBuilder.setDistinct(true);
smsQueryBuilder.setDistinct(true);
mmsQueryBuilder.setTables(joinPduAndPendingMsgTables());
smsQueryBuilder.setTables(SmsProvider.TABLE_SMS);
String[] smsColumns = handleNullMessageProjection(projection);
String[] mmsColumns = handleNullMessageProjection(mmsProjection);
String[] innerMmsProjection = makeProjectionWithNormalizedDate(mmsColumns, 1000);
String[] innerSmsProjection = makeProjectionWithNormalizedDate(smsColumns, 1);
Set<String> columnsPresentInTable = new HashSet<String>(MMS_COLUMNS);
columnsPresentInTable.add("pdu._id");
columnsPresentInTable.add(PendingMessages.ERROR_TYPE);
String mmsSelection = concatSelections(selection,
Mms.MESSAGE_BOX + " != " + Mms.MESSAGE_BOX_DRAFTS);
String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection,
columnsPresentInTable, 0, "mms",
concatSelections(mmsSelection, MMS_CONVERSATION_CONSTRAINT),
selectionArgs, null, null);
String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection, SMS_COLUMNS,
0, "sms", concatSelections(selection, SMS_CONVERSATION_CONSTRAINT),
selectionArgs, null, null);
SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
unionQueryBuilder.setDistinct(true);
String unionQuery = unionQueryBuilder.buildUnionQuery(
new String[] { smsSubQuery, mmsSubQuery },
handleNullSortOrder(sortOrder), null);
SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder();
outerQueryBuilder.setTables("(" + unionQuery + ")");
return outerQueryBuilder.buildQuery(
smsColumns, null, null, null, null, sortOrder, null);
| private static java.lang.String | concatSelections(java.lang.String selection1, java.lang.String selection2)
if (TextUtils.isEmpty(selection1)) {
return selection2;
} else if (TextUtils.isEmpty(selection2)) {
return selection1;
} else {
return selection1 + " AND " + selection2;
}
| private static java.lang.String[] | createMmsProjection(java.lang.String[] old)
String[] newProjection = new String[old.length];
for (int i = 0; i < old.length; i++) {
if (old[i].equals(BaseColumns._ID)) {
newProjection[i] = "pdu._id";
} else {
newProjection[i] = old[i];
}
}
return newProjection;
| public int | delete(android.net.Uri uri, java.lang.String selection, java.lang.String[] selectionArgs)
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
Context context = getContext();
int affectedRows = 0;
switch(URI_MATCHER.match(uri)) {
case URI_CONVERSATIONS_MESSAGES:
long threadId;
try {
threadId = Long.parseLong(uri.getLastPathSegment());
} catch (NumberFormatException e) {
Log.e(LOG_TAG, "Thread ID must be a long.");
break;
}
affectedRows = deleteConversation(uri, selection, selectionArgs);
MmsSmsDatabaseHelper.updateThread(db, threadId);
break;
case URI_CONVERSATIONS:
affectedRows = MmsProvider.deleteMessages(context, db,
selection, selectionArgs, uri)
+ db.delete("sms", selection, selectionArgs);
MmsSmsDatabaseHelper.updateAllThreads(db, selection, selectionArgs);
break;
case URI_OBSOLETE_THREADS:
affectedRows = db.delete("threads",
"_id NOT IN (SELECT DISTINCT thread_id FROM sms " +
"UNION SELECT DISTINCT thread_id FROM pdu)", null);
break;
default:
throw new UnsupportedOperationException(NO_DELETES_INSERTS_OR_UPDATES);
}
if (affectedRows > 0) {
context.getContentResolver().notifyChange(MmsSms.CONTENT_URI, null);
}
return affectedRows;
| private int | deleteConversation(android.net.Uri uri, java.lang.String selection, java.lang.String[] selectionArgs)Delete the conversation with the given thread ID.
String threadId = uri.getLastPathSegment();
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
String finalSelection = concatSelections(selection, "thread_id = " + threadId);
return MmsProvider.deleteMessages(getContext(), db, finalSelection,
selectionArgs, uri)
+ db.delete("sms", finalSelection, selectionArgs);
| private java.util.Set | getAddressIds(java.util.List addresses)Return the canonical address IDs for these addresses.
Set<Long> result = new HashSet<Long>(addresses.size());
for (String address : addresses) {
if (!address.equals(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) {
long id = getSingleAddressId(address);
if (id != -1L) {
result.add(id);
} else {
Log.e(LOG_TAG, "Address ID not found for: " + address);
}
}
}
return result;
| private android.database.Cursor | getCompleteConversations(java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)Return every message in each conversation in both MMS
and SMS.
String unionQuery = buildConversationQuery(
projection, selection, selectionArgs, sortOrder);
return mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY);
| private android.database.Cursor | getConversationById(java.lang.String threadIdString, java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)Return the conversation of certain thread ID.
try {
Long.parseLong(threadIdString);
} catch (NumberFormatException exception) {
Log.e(LOG_TAG, "Thread ID must be a Long.");
return null;
}
String extraSelection = "_id=" + threadIdString;
String finalSelection = concatSelections(selection, extraSelection);
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
String[] columns = handleNullThreadsProjection(projection);
queryBuilder.setDistinct(true);
queryBuilder.setTables("threads");
return queryBuilder.query(
mOpenHelper.getReadableDatabase(), columns, finalSelection,
selectionArgs, sortOrder, null, null);
| private android.database.Cursor | getConversationMessages(java.lang.String threadIdString, java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)Return the union of MMS and SMS messages for this thread ID.
try {
Long.parseLong(threadIdString);
} catch (NumberFormatException exception) {
Log.e(LOG_TAG, "Thread ID must be a Long.");
return null;
}
String finalSelection = concatSelections(
selection, "thread_id = " + threadIdString);
String unionQuery = buildConversationQuery(
projection, finalSelection, selectionArgs, sortOrder);
return mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY);
| private android.database.Cursor | getConversations(java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)Return the most recent message in each conversation in both MMS
and SMS.
Use this query:
SELECT ...
FROM (SELECT thread_id AS tid, date * 1000 AS normalized_date, ...
FROM pdu
WHERE msg_box != 3 AND ...
GROUP BY thread_id
HAVING date = MAX(date)
UNION
SELECT thread_id AS tid, date AS normalized_date, ...
FROM sms
WHERE ...
GROUP BY thread_id
HAVING date = MAX(date))
GROUP BY tid
HAVING normalized_date = MAX(normalized_date);
The msg_box != 3 comparisons ensure that we don't include draft
messages.
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
mmsQueryBuilder.setTables(MmsProvider.TABLE_PDU);
smsQueryBuilder.setTables(SmsProvider.TABLE_SMS);
String[] columns = handleNullMessageProjection(projection);
String[] innerMmsProjection = makeProjectionWithDateAndThreadId(
UNION_COLUMNS, 1000);
String[] innerSmsProjection = makeProjectionWithDateAndThreadId(
UNION_COLUMNS, 1);
String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection,
MMS_COLUMNS, 1, "mms",
concatSelections(selection, MMS_CONVERSATION_CONSTRAINT), selectionArgs,
"thread_id", "date = MAX(date)");
String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection,
SMS_COLUMNS, 1, "sms",
concatSelections(selection, SMS_CONVERSATION_CONSTRAINT), selectionArgs,
"thread_id", "date = MAX(date)");
SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
unionQueryBuilder.setDistinct(true);
String unionQuery = unionQueryBuilder.buildUnionQuery(
new String[] { mmsSubQuery, smsSubQuery }, null, null);
SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder();
outerQueryBuilder.setTables("(" + unionQuery + ")");
String outerQuery = outerQueryBuilder.buildQuery(
columns, null, null, "tid",
"normalized_date = MAX(normalized_date)", sortOrder, null);
return mOpenHelper.getReadableDatabase().rawQuery(outerQuery, EMPTY_STRING_ARRAY);
| private android.database.Cursor | getDraftThread(java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)Return the thread which has draft in both MMS and SMS.
Use this query:
SELECT ...
FROM (SELECT _id, thread_id, ...
FROM pdu
WHERE msg_box = 3 AND ...
UNION
SELECT _id, thread_id, ...
FROM sms
WHERE type = 3 AND ...
)
;
String[] innerProjection = new String[] {BaseColumns._ID, Conversations.THREAD_ID};
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
mmsQueryBuilder.setTables(MmsProvider.TABLE_PDU);
smsQueryBuilder.setTables(SmsProvider.TABLE_SMS);
String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerProjection,
MMS_COLUMNS, 1, "mms",
concatSelections(selection, Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_DRAFTS),
selectionArgs, null, null);
String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerProjection,
SMS_COLUMNS, 1, "sms",
concatSelections(selection, Sms.TYPE + "=" + Sms.MESSAGE_TYPE_DRAFT),
selectionArgs, null, null);
SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
unionQueryBuilder.setDistinct(true);
String unionQuery = unionQueryBuilder.buildUnionQuery(
new String[] { mmsSubQuery, smsSubQuery }, null, null);
SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder();
outerQueryBuilder.setTables("(" + unionQuery + ")");
String outerQuery = outerQueryBuilder.buildQuery(
projection, null, null, null, null, sortOrder, null);
return mOpenHelper.getReadableDatabase().rawQuery(outerQuery, EMPTY_STRING_ARRAY);
| private android.database.Cursor | getMessagesByPhoneNumber(java.lang.String phoneNumber, java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)Return the union of MMS and SMS messages whose recipients
included this phone number.
Use this query:
SELECT ...
FROM pdu, (SELECT _id AS address_id
FROM addr
WHERE PHONE_NUMBERS_EQUAL(addr.address, ''))
AS matching_addresses
WHERE pdu._id = matching_addresses.address_id
UNION
SELECT ...
FROM sms
WHERE PHONE_NUMBERS_EQUAL(sms.address, '');
String escapedPhoneNumber = DatabaseUtils.sqlEscapeString(phoneNumber);
String finalMmsSelection =
concatSelections(
selection,
"pdu._id = matching_addresses.address_id");
String finalSmsSelection =
concatSelections(
selection,
"PHONE_NUMBERS_EQUAL(address, " +
escapedPhoneNumber + ")");
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
mmsQueryBuilder.setDistinct(true);
smsQueryBuilder.setDistinct(true);
mmsQueryBuilder.setTables(
MmsProvider.TABLE_PDU +
", (SELECT _id AS address_id " +
"FROM addr WHERE PHONE_NUMBERS_EQUAL(addr.address, " +
escapedPhoneNumber + ")) " +
"AS matching_addresses");
smsQueryBuilder.setTables(SmsProvider.TABLE_SMS);
String[] columns = handleNullMessageProjection(projection);
String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, columns, MMS_COLUMNS,
0, "mms", finalMmsSelection, selectionArgs, null, null);
String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, columns, SMS_COLUMNS,
0, "sms", finalSmsSelection, selectionArgs, null, null);
SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
unionQueryBuilder.setDistinct(true);
String unionQuery = unionQueryBuilder.buildUnionQuery(
new String[] { mmsSubQuery, smsSubQuery }, sortOrder, null);
return mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY);
| private android.database.Cursor | getSimpleConversations(java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)Return existing threads in the database.
return mOpenHelper.getReadableDatabase().query("threads", projection,
selection, selectionArgs, null, null, " date DESC");
| private long | getSingleAddressId(java.lang.String address)Return the canonical address ID for this address.
boolean isEmail = Mms.isEmailAddress(address);
String refinedAddress = isEmail ? address.toLowerCase() : address;
String selection =
isEmail
? "address = ?"
: "PHONE_NUMBERS_EQUAL(address, ?)";
String[] selectionArgs = new String[] { 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) {
ContentValues contentValues = new ContentValues(1);
contentValues.put(CanonicalAddressesColumns.ADDRESS, refinedAddress);
db = mOpenHelper.getWritableDatabase();
return db.insert("canonical_addresses",
CanonicalAddressesColumns.ADDRESS, contentValues);
}
if (cursor.moveToFirst()) {
return cursor.getLong(cursor.getColumnIndexOrThrow(BaseColumns._ID));
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return -1L;
| private long[] | getSortedSet(java.util.Set numbers)Return a sorted array of the given Set of Longs.
int size = numbers.size();
long[] result = new long[size];
int i = 0;
for (Long number : numbers) {
result[i++] = number;
}
Arrays.sort(result);
return result;
| private java.lang.String | getSpaceSeparatedNumbers(long[] numbers)Return a String of the numbers in the given array, in order,
separated by spaces.
int size = numbers.length;
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < size; i++) {
if (i != 0) {
buffer.append(' ");
}
buffer.append(numbers[i]);
}
return buffer.toString();
| private synchronized android.database.Cursor | getThreadId(java.util.List recipients)Return the thread ID for this list of
recipients IDs. If no thread exists with this ID, create
one and return it. Callers should always use
Threads.getThreadId to access this information.
String recipientIds =
getSpaceSeparatedNumbers(
getSortedSet(getAddressIds(recipients)));
String THREAD_QUERY = "SELECT _id FROM threads " +
"WHERE recipient_ids = ?";
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor cursor = db.rawQuery(THREAD_QUERY, new String[] { recipientIds });
if (cursor.getCount() == 0) {
cursor.close();
insertThread(recipientIds, recipients.size());
db = mOpenHelper.getReadableDatabase(); // In case insertThread closed it
cursor = db.rawQuery(THREAD_QUERY, new String[] { recipientIds });
}
return cursor;
| public java.lang.String | getType(android.net.Uri uri)
return VND_ANDROID_DIR_MMS_SMS;
| private android.database.Cursor | getUndeliveredMessages(java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)
String[] mmsProjection = createMmsProjection(projection);
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
mmsQueryBuilder.setTables(joinPduAndPendingMsgTables());
smsQueryBuilder.setTables(SmsProvider.TABLE_SMS);
String finalMmsSelection = concatSelections(
selection, Mms.MESSAGE_BOX + " = " + Mms.MESSAGE_BOX_OUTBOX);
String finalSmsSelection = concatSelections(
selection, "(" + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_OUTBOX
+ " OR " + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_FAILED
+ " OR " + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_QUEUED + ")");
String[] smsColumns = handleNullMessageProjection(projection);
String[] mmsColumns = handleNullMessageProjection(mmsProjection);
String[] innerMmsProjection = makeProjectionWithDateAndThreadId(
mmsColumns, 1000);
String[] innerSmsProjection = makeProjectionWithDateAndThreadId(
smsColumns, 1);
Set<String> columnsPresentInTable = new HashSet<String>(MMS_COLUMNS);
columnsPresentInTable.add("pdu._id");
columnsPresentInTable.add(PendingMessages.ERROR_TYPE);
String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection,
columnsPresentInTable, 1, "mms", finalMmsSelection, selectionArgs,
null, null);
String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection,
SMS_COLUMNS, 1, "sms", finalSmsSelection, selectionArgs,
null, null);
SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
unionQueryBuilder.setDistinct(true);
String unionQuery = unionQueryBuilder.buildUnionQuery(
new String[] { smsSubQuery, mmsSubQuery }, null, null);
SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder();
outerQueryBuilder.setTables("(" + unionQuery + ")");
String outerQuery = outerQueryBuilder.buildQuery(
smsColumns, null, null, null, null, sortOrder, null);
return mOpenHelper.getReadableDatabase().rawQuery(outerQuery, EMPTY_STRING_ARRAY);
| private static java.lang.String[] | handleNullMessageProjection(java.lang.String[] projection)If a null projection is given, return the union of all columns
in both the MMS and SMS messages tables. Otherwise, return the
given projection.
return projection == null ? UNION_COLUMNS : projection;
| private static java.lang.String | handleNullSortOrder(java.lang.String sortOrder)If a null sort order is given, return "normalized_date ASC".
Otherwise, return the given sort order.
return sortOrder == null ? "normalized_date ASC" : sortOrder;
| private static java.lang.String[] | handleNullThreadsProjection(java.lang.String[] projection)If a null projection is given, return the set of all columns in
the threads table. Otherwise, return the given projection.
return projection == null ? THREADS_COLUMNS : projection;
| private static void | initializeColumnSets()Construct Sets of Strings containing exactly the columns
present in each table. We will use this when constructing
UNION queries across the MMS and SMS tables.
int commonColumnCount = MMS_SMS_COLUMNS.length;
int mmsOnlyColumnCount = MMS_ONLY_COLUMNS.length;
int smsOnlyColumnCount = SMS_ONLY_COLUMNS.length;
Set<String> unionColumns = new HashSet<String>();
for (int i = 0; i < commonColumnCount; i++) {
MMS_COLUMNS.add(MMS_SMS_COLUMNS[i]);
SMS_COLUMNS.add(MMS_SMS_COLUMNS[i]);
unionColumns.add(MMS_SMS_COLUMNS[i]);
}
for (int i = 0; i < mmsOnlyColumnCount; i++) {
MMS_COLUMNS.add(MMS_ONLY_COLUMNS[i]);
unionColumns.add(MMS_ONLY_COLUMNS[i]);
}
for (int i = 0; i < smsOnlyColumnCount; i++) {
SMS_COLUMNS.add(SMS_ONLY_COLUMNS[i]);
unionColumns.add(SMS_ONLY_COLUMNS[i]);
}
int i = 0;
for (String columnName : unionColumns) {
UNION_COLUMNS[i++] = columnName;
}
| public android.net.Uri | insert(android.net.Uri uri, android.content.ContentValues values)
throw new UnsupportedOperationException(NO_DELETES_INSERTS_OR_UPDATES);
| private void | insertThread(java.lang.String recipientIds, int numberOfRecipients)Insert a record for a new thread.
ContentValues values = new ContentValues(4);
long date = System.currentTimeMillis();
values.put(ThreadsColumns.DATE, date - date % 1000);
values.put(ThreadsColumns.RECIPIENT_IDS, recipientIds);
if (numberOfRecipients > 1) {
values.put(Threads.TYPE, Threads.BROADCAST_THREAD);
}
values.put(ThreadsColumns.MESSAGE_COUNT, 0);
mOpenHelper.getWritableDatabase().insert("threads", null, values);
getContext().getContentResolver().notifyChange(MmsSms.CONTENT_URI, null);
| private static java.lang.String | joinPduAndPendingMsgTables()
return MmsProvider.TABLE_PDU + " LEFT JOIN " + TABLE_PENDING_MSG
+ " ON pdu._id = pending_msgs.msg_id";
| private java.lang.String[] | makeProjectionWithDateAndThreadId(java.lang.String[] projection, int dateMultiple)Add normalized date and thread_id to the list of columns for an
inner projection. This is necessary so that the outer query
can have access to these columns even if the caller hasn't
requested them in the result.
int projectionSize = projection.length;
String[] result = new String[projectionSize + 2];
result[0] = "thread_id AS tid";
result[1] = "date * " + dateMultiple + " AS normalized_date";
for (int i = 0; i < projectionSize; i++) {
result[i + 2] = projection[i];
}
return result;
| private static java.lang.String[] | makeProjectionWithNormalizedDate(java.lang.String[] projection, int dateMultiple)Add normalized date to the list of columns for an inner
projection.
int projectionSize = projection.length;
String[] result = new String[projectionSize + 1];
result[0] = "date * " + dateMultiple + " AS normalized_date";
System.arraycopy(projection, 0, result, 1, projectionSize);
return result;
| public boolean | onCreate()
mOpenHelper = MmsSmsDatabaseHelper.getInstance(getContext());
return true;
| public android.database.Cursor | query(android.net.Uri uri, java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor cursor = null;
switch(URI_MATCHER.match(uri)) {
case URI_COMPLETE_CONVERSATIONS:
cursor = getCompleteConversations(
projection, selection, selectionArgs, sortOrder);
break;
case URI_CONVERSATIONS:
String simple = uri.getQueryParameter("simple");
if ((simple != null) && simple.equals("true")) {
String threadType = uri.getQueryParameter("thread_type");
if (!TextUtils.isEmpty(threadType)) {
selection = concatSelections(
selection, Threads.TYPE + "=" + threadType);
}
cursor = getSimpleConversations(
projection, selection, selectionArgs, sortOrder);
} else {
cursor = getConversations(
projection, selection, selectionArgs, sortOrder);
}
break;
case URI_CONVERSATIONS_MESSAGES:
cursor = getConversationMessages(
uri.getPathSegments().get(1), projection, selection,
selectionArgs, sortOrder);
break;
case URI_CONVERSATIONS_RECIPIENTS:
cursor = getConversationById(
uri.getPathSegments().get(1), projection, selection,
selectionArgs, sortOrder);
break;
case URI_CONVERSATIONS_SUBJECT:
cursor = getConversationById(
uri.getPathSegments().get(1), projection, selection,
selectionArgs, sortOrder);
break;
case URI_MESSAGES_BY_PHONE:
cursor = getMessagesByPhoneNumber(
uri.getPathSegments().get(2), projection, selection,
selectionArgs, sortOrder);
break;
case URI_THREAD_ID:
List<String> recipients = uri.getQueryParameters("recipient");
cursor = getThreadId(recipients);
break;
case URI_CANONICAL_ADDRESS: {
String extraSelection = "_id=" + uri.getPathSegments().get(1);
String finalSelection = TextUtils.isEmpty(selection)
? extraSelection : extraSelection + " AND " + selection;
cursor = db.query("canonical_addresses",
new String[] {"address"}, finalSelection, selectionArgs,
null, null, sortOrder);
break;
}
case URI_PENDING_MSG: {
String protoName = uri.getQueryParameter("protocol");
String msgId = uri.getQueryParameter("message");
int proto = TextUtils.isEmpty(protoName) ? -1
: (protoName.equals("sms") ? MmsSms.SMS_PROTO : MmsSms.MMS_PROTO);
String extraSelection = (proto != -1) ?
(PendingMessages.PROTO_TYPE + "=" + proto) : " 0=0 ";
if (!TextUtils.isEmpty(msgId)) {
extraSelection += " AND " + PendingMessages.MSG_ID + "=" + msgId;
}
String finalSelection = TextUtils.isEmpty(selection)
? extraSelection : ("(" + extraSelection + ") AND " + selection);
String finalOrder = TextUtils.isEmpty(sortOrder)
? PendingMessages.DUE_TIME : sortOrder;
cursor = db.query(TABLE_PENDING_MSG, null,
finalSelection, selectionArgs, null, null, finalOrder);
break;
}
case URI_UNDELIVERED_MSG: {
cursor = getUndeliveredMessages(projection, selection,
selectionArgs, sortOrder);
break;
}
case URI_DRAFT: {
cursor = getDraftThread(projection, selection, selectionArgs, sortOrder);
break;
}
default:
throw new IllegalStateException("Unrecognized URI:" + uri);
}
cursor.setNotificationUri(getContext().getContentResolver(), MmsSms.CONTENT_URI);
return cursor;
| public int | update(android.net.Uri uri, android.content.ContentValues values, java.lang.String selection, java.lang.String[] selectionArgs)
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int affectedRows = 0;
switch(URI_MATCHER.match(uri)) {
case URI_CONVERSATIONS_MESSAGES:
String threadIdString = uri.getPathSegments().get(1);
affectedRows = updateConversation(threadIdString, values,
selection, selectionArgs);
break;
case URI_PENDING_MSG:
affectedRows = db.update(TABLE_PENDING_MSG, values, selection, null);
break;
default:
throw new UnsupportedOperationException(
NO_DELETES_INSERTS_OR_UPDATES);
}
if (affectedRows > 0) {
getContext().getContentResolver().notifyChange(
MmsSms.CONTENT_URI, null);
}
return affectedRows;
| private int | updateConversation(java.lang.String threadIdString, android.content.ContentValues values, java.lang.String selection, java.lang.String[] selectionArgs)
try {
Long.parseLong(threadIdString);
} catch (NumberFormatException exception) {
Log.e(LOG_TAG, "Thread ID must be a Long.");
return 0;
}
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
String finalSelection = concatSelections(selection, "thread_id=" + threadIdString);
return db.update(MmsProvider.TABLE_PDU, values, finalSelection, selectionArgs)
+ db.update("sms", values, finalSelection, selectionArgs);
|
|