SmsProviderpublic class SmsProvider extends android.content.ContentProvider
Fields Summary |
---|
private static final android.net.Uri | NOTIFICATION_URI | private static final android.net.Uri | SIM_URI | static final String | TABLE_SMS | private static final String | TABLE_RAW | private static final String | TABLE_SR_PENDING | private static final Integer | ONE | private static final String[] | SIM_COLUMNSThese are the columns that are available when reading SMS
messages from the SIM. Columns whose names begin with "is_"
have either "true" or "false" as their values. | private android.database.sqlite.SQLiteOpenHelper | mOpenHelper | private static final String | TAG | private static final String | VND_ANDROID_SMS | private static final String | VND_ANDROID_SMSCHAT | private static final String | VND_ANDROID_DIR_SMS | private static final HashMap | sConversationProjectionMap | private static final String[] | sIDProjection | private static final int | SMS_ALL | private static final int | SMS_ALL_ID | private static final int | SMS_INBOX | private static final int | SMS_INBOX_ID | private static final int | SMS_SENT | private static final int | SMS_SENT_ID | private static final int | SMS_DRAFT | private static final int | SMS_DRAFT_ID | private static final int | SMS_OUTBOX | private static final int | SMS_OUTBOX_ID | private static final int | SMS_CONVERSATIONS | private static final int | SMS_CONVERSATIONS_ID | private static final int | SMS_RAW_MESSAGE | private static final int | SMS_ATTACHMENT | private static final int | SMS_ATTACHMENT_ID | private static final int | SMS_NEW_THREAD_ID | private static final int | SMS_QUERY_THREAD_ID | private static final int | SMS_STATUS_ID | private static final int | SMS_STATUS_PENDING | private static final int | SMS_ALL_SIM | private static final int | SMS_SIM | private static final int | SMS_FAILED | private static final int | SMS_FAILED_ID | private static final int | SMS_QUEUED | private static final int | SMS_UNDELIVERED | private static final android.content.UriMatcher | sURLMatcher |
Methods Summary |
---|
private void | constructQueryForBox(android.database.sqlite.SQLiteQueryBuilder qb, int type)
qb.setTables(TABLE_SMS);
if (type != Sms.MESSAGE_TYPE_ALL) {
qb.appendWhere("type=" + type);
}
| private void | constructQueryForUndelivered(android.database.sqlite.SQLiteQueryBuilder qb)
qb.setTables(TABLE_SMS);
qb.appendWhere("(type=" + Sms.MESSAGE_TYPE_OUTBOX +
" OR type=" + Sms.MESSAGE_TYPE_FAILED +
" OR type=" + Sms.MESSAGE_TYPE_QUEUED + ")");
| private java.util.ArrayList | convertSimToSms(android.telephony.gsm.SmsMessage message)
ArrayList result = new ArrayList();
// N.B.: These calls must appear in the same order as the
// columns appear in SIM_COLUMNS.
result.add(message.getServiceCenterAddress());
result.add(message.getDisplayOriginatingAddress());
result.add(message.getMessageClass().toString());
result.add(message.getDisplayMessageBody());
result.add(message.getTimestampMillis());
result.add(Sms.STATUS_NONE);
result.add(message.getIndexOnSim());
result.add(message.isStatusReportMessage());
result.add("sms");
result.add(TextBasedSmsColumns.MESSAGE_TYPE_ALL);
return result;
| public int | delete(android.net.Uri url, java.lang.String where, java.lang.String[] whereArgs)
int count;
int match = sURLMatcher.match(url);
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
switch (match) {
case SMS_ALL:
count = db.delete(TABLE_SMS, where, whereArgs);
if (count != 0) {
// Don't update threads unless something changed.
MmsSmsDatabaseHelper.updateAllThreads(db, where, whereArgs);
}
break;
case SMS_ALL_ID:
try {
int message_id = Integer.parseInt(url.getPathSegments().get(0));
count = MmsSmsDatabaseHelper.deleteOneSms(db, message_id);
} catch (Exception e) {
throw new IllegalArgumentException(
"Bad message id: " + url.getPathSegments().get(0));
}
break;
case SMS_CONVERSATIONS_ID:
int threadID;
try {
threadID = Integer.parseInt(url.getPathSegments().get(1));
} catch (Exception ex) {
throw new IllegalArgumentException(
"Bad conversation thread id: "
+ url.getPathSegments().get(1));
}
// delete the messages from the sms table
where = DatabaseUtils.concatenateWhere("thread_id=" + threadID, where);
count = db.delete(TABLE_SMS, where, whereArgs);
MmsSmsDatabaseHelper.updateThread(db, threadID);
break;
case SMS_RAW_MESSAGE:
count = db.delete("raw", where, whereArgs);
break;
case SMS_STATUS_PENDING:
count = db.delete("sr_pending", where, whereArgs);
break;
case SMS_SIM:
String messageIndexString = url.getPathSegments().get(1);
return deleteMessageFromSim(messageIndexString);
default:
throw new IllegalArgumentException("Unknown URL");
}
if (count > 0) {
notifyChange(url);
}
return count;
| private int | deleteMessageFromSim(java.lang.String messageIndexString)Delete the message at index from SIM. Return true iff
successful.
SmsManager smsManager = SmsManager.getDefault();
try {
return smsManager.deleteMessageFromSim(
Integer.parseInt(messageIndexString))
? 1 : 0;
} catch (NumberFormatException exception) {
throw new IllegalArgumentException(
"Bad SMS SIM ID: " + messageIndexString);
} finally {
ContentResolver cr = getContext().getContentResolver();
cr.notifyChange(SIM_URI, null);
}
| private android.database.Cursor | getAllMessagesFromSim()Return a Cursor listing all the messages stored on the SIM.
SmsManager smsManager = SmsManager.getDefault();
ArrayList<SmsMessage> messages = smsManager.getAllMessagesFromSim();
ArrayList<ArrayList> rows = new ArrayList<ArrayList>();
for (int count = messages.size(), i = 0; i < count; i++) {
SmsMessage message = messages.get(i);
if (message != null) {
rows.add(convertSimToSms(message));
}
}
return withSimNotificationUri(new ArrayListCursor(SIM_COLUMNS, rows));
| private android.database.Cursor | getSingleMessageFromSim(java.lang.String messageIndexString)Return a Cursor containing just one message from the SIM.
try {
int messageIndex = Integer.parseInt(messageIndexString);
SmsManager smsManager = SmsManager.getDefault();
ArrayList<SmsMessage> messages = smsManager.getAllMessagesFromSim();
ArrayList<ArrayList> singleRow = new ArrayList<ArrayList>();
SmsMessage message = messages.get(messageIndex);
if (message == null) {
throw new IllegalArgumentException(
"Message not retrieved. ID: " + messageIndexString);
}
singleRow.add(convertSimToSms(message));
return withSimNotificationUri(
new ArrayListCursor(SIM_COLUMNS, singleRow));
} catch (NumberFormatException exception) {
throw new IllegalArgumentException(
"Bad SMS SIM ID: " + messageIndexString);
}
| public java.lang.String | getType(android.net.Uri url)
switch (url.getPathSegments().size()) {
case 0:
return VND_ANDROID_DIR_SMS;
case 1:
try {
Integer.parseInt(url.getPathSegments().get(0));
return VND_ANDROID_SMS;
} catch (NumberFormatException ex) {
return VND_ANDROID_DIR_SMS;
}
case 2:
// TODO: What about "threadID"?
if (url.getPathSegments().get(0).equals("conversations")) {
return VND_ANDROID_SMSCHAT;
} else {
return VND_ANDROID_SMS;
}
}
return null;
| public android.net.Uri | insert(android.net.Uri url, android.content.ContentValues initialValues)
ContentValues values;
long rowID;
int type = Sms.MESSAGE_TYPE_ALL;
int match = sURLMatcher.match(url);
if (Config.LOGD) {
Log.d(TAG, "insert url=" + url + ", match=" + match);
}
String table = TABLE_SMS;
switch (match) {
case SMS_ALL:
Integer typeObj = initialValues.getAsInteger(Sms.TYPE);
if (typeObj != null) {
type = typeObj.intValue();
} else {
// default to inbox
type = Sms.MESSAGE_TYPE_INBOX;
}
break;
case SMS_INBOX:
type = Sms.MESSAGE_TYPE_INBOX;
break;
case SMS_FAILED:
type = Sms.MESSAGE_TYPE_FAILED;
break;
case SMS_QUEUED:
type = Sms.MESSAGE_TYPE_QUEUED;
break;
case SMS_SENT:
type = Sms.MESSAGE_TYPE_SENT;
break;
case SMS_DRAFT:
type = Sms.MESSAGE_TYPE_DRAFT;
break;
case SMS_OUTBOX:
type = Sms.MESSAGE_TYPE_OUTBOX;
break;
case SMS_RAW_MESSAGE:
table = "raw";
break;
case SMS_STATUS_PENDING:
table = "sr_pending";
break;
case SMS_ATTACHMENT:
table = "attachments";
break;
case SMS_NEW_THREAD_ID:
table = "canonical_addresses";
break;
default:
Log.e(TAG, "Invalid request: " + url);
return null;
}
if (table.equals(TABLE_SMS)) {
boolean addDate = false;
boolean addType = false;
// Make sure that the date and type are set
if (initialValues == null) {
values = new ContentValues(1);
addDate = true;
addType = true;
} else {
values = new ContentValues(initialValues);
if (!initialValues.containsKey(Sms.DATE)) {
addDate = true;
}
if (!initialValues.containsKey(Sms.TYPE)) {
addType = true;
}
}
if (addDate) {
values.put(Sms.DATE, new Long(System.currentTimeMillis()));
}
if (addType && (type != Sms.MESSAGE_TYPE_ALL)) {
values.put(Sms.TYPE, Integer.valueOf(type));
}
// thread_id
Long threadId = values.getAsLong(Sms.THREAD_ID);
String address = values.getAsString(Sms.ADDRESS);
if (((threadId == null) || (threadId == 0)) && (address != null)) {
values.put(Sms.THREAD_ID, Threads.getOrCreateThreadId(
getContext(), address));
}
if (type == Sms.MESSAGE_TYPE_INBOX) {
// Look up the person if not already filled in.
if ((values.getAsLong(Sms.PERSON) == null)
&& (!TextUtils.isEmpty(address))) {
Cursor cursor = getContext().getContentResolver().query(
Uri.withAppendedPath(
Contacts.Phones.CONTENT_FILTER_URL, address),
new String[] { Contacts.Phones.PERSON_ID },
null, null, null);
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
Long id = Long.valueOf(cursor.getLong(0));
values.put(Sms.PERSON, id);
}
cursor.deactivate();
}
}
} else {
// Mark all non-inbox messages read.
values.put(Sms.READ, ONE);
}
} else {
if (initialValues == null) {
values = new ContentValues(1);
} else {
values = initialValues;
}
}
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
rowID = db.insert(table, "body", values);
if (rowID > 0) {
Uri uri = Uri.parse("content://" + table + "/" + rowID);
notifyChange(uri);
return uri;
} else {
Log.e(TAG,
"SmsProvider.insert: failed! " + values.toString());
}
return null;
| private void | notifyChange(android.net.Uri uri)
ContentResolver cr = getContext().getContentResolver();
cr.notifyChange(uri, null);
cr.notifyChange(MmsSms.CONTENT_URI, null);
cr.notifyChange(Uri.parse("content://mms-sms/conversations/"), null);
| public boolean | onCreate()
mOpenHelper = MmsSmsDatabaseHelper.getInstance(getContext());
return true;
| public android.database.Cursor | query(android.net.Uri url, java.lang.String[] projectionIn, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sort)
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
// Generate the body of the query.
int match = sURLMatcher.match(url);
switch (match) {
case SMS_ALL:
constructQueryForBox(qb, Sms.MESSAGE_TYPE_ALL);
break;
case SMS_UNDELIVERED:
constructQueryForUndelivered(qb);
break;
case SMS_FAILED:
constructQueryForBox(qb, Sms.MESSAGE_TYPE_FAILED);
break;
case SMS_QUEUED:
constructQueryForBox(qb, Sms.MESSAGE_TYPE_QUEUED);
break;
case SMS_INBOX:
constructQueryForBox(qb, Sms.MESSAGE_TYPE_INBOX);
break;
case SMS_SENT:
constructQueryForBox(qb, Sms.MESSAGE_TYPE_SENT);
break;
case SMS_DRAFT:
constructQueryForBox(qb, Sms.MESSAGE_TYPE_DRAFT);
break;
case SMS_OUTBOX:
constructQueryForBox(qb, Sms.MESSAGE_TYPE_OUTBOX);
break;
case SMS_ALL_ID:
qb.setTables(TABLE_SMS);
qb.appendWhere("(_id = " + url.getPathSegments().get(0) + ")");
break;
case SMS_INBOX_ID:
case SMS_FAILED_ID:
case SMS_SENT_ID:
case SMS_DRAFT_ID:
case SMS_OUTBOX_ID:
qb.setTables(TABLE_SMS);
qb.appendWhere("(_id = " + url.getPathSegments().get(1) + ")");
break;
case SMS_CONVERSATIONS_ID:
int threadID;
try {
threadID = Integer.parseInt(url.getPathSegments().get(1));
if (Config.LOGD) {
Log.d(TAG, "query conversations: threadID=" + threadID);
}
}
catch (Exception ex) {
Log.e(TAG,
"Bad conversation thread id: "
+ url.getPathSegments().get(1));
return null;
}
qb.setTables(TABLE_SMS);
qb.appendWhere("thread_id = " + threadID);
break;
case SMS_CONVERSATIONS:
qb.setTables("sms, (SELECT thread_id AS group_thread_id, MAX(date) AS group_date, COUNT(*) AS msg_count FROM sms GROUP BY thread_id) AS groups");
qb.appendWhere("sms.thread_id = groups.group_thread_id AND sms.date = groups.group_date");
qb.setProjectionMap(sConversationProjectionMap);
break;
case SMS_RAW_MESSAGE:
qb.setTables("raw");
break;
case SMS_STATUS_PENDING:
qb.setTables("sr_pending");
break;
case SMS_ATTACHMENT:
qb.setTables("attachments");
break;
case SMS_ATTACHMENT_ID:
qb.setTables("attachments");
qb.appendWhere(
"(sms_id = " + url.getPathSegments().get(1) + ")");
break;
case SMS_QUERY_THREAD_ID:
qb.setTables("canonical_addresses");
if (projectionIn == null) {
projectionIn = sIDProjection;
}
break;
case SMS_STATUS_ID:
qb.setTables(TABLE_SMS);
qb.appendWhere("(_id = " + url.getPathSegments().get(1) + ")");
break;
case SMS_ALL_SIM:
return getAllMessagesFromSim();
case SMS_SIM:
String messageIndexString = url.getPathSegments().get(1);
return getSingleMessageFromSim(messageIndexString);
default:
Log.e(TAG, "Invalid request: " + url);
return null;
}
String orderBy = null;
if (!TextUtils.isEmpty(sort)) {
orderBy = sort;
} else if (qb.getTables().equals(TABLE_SMS)) {
orderBy = Sms.DEFAULT_SORT_ORDER;
}
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor ret = qb.query(db, projectionIn, selection, selectionArgs,
null, null, orderBy);
// TODO: Since the URLs are a mess, always use content://sms
ret.setNotificationUri(getContext().getContentResolver(),
NOTIFICATION_URI);
return ret;
| public int | update(android.net.Uri url, android.content.ContentValues values, java.lang.String where, java.lang.String[] whereArgs)
int count = 0;
String table = TABLE_SMS;
String extraWhere = null;
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
switch (sURLMatcher.match(url)) {
case SMS_RAW_MESSAGE:
table = TABLE_RAW;
break;
case SMS_STATUS_PENDING:
table = TABLE_SR_PENDING;
break;
case SMS_ALL:
case SMS_FAILED:
case SMS_QUEUED:
case SMS_INBOX:
case SMS_SENT:
case SMS_DRAFT:
case SMS_OUTBOX:
case SMS_CONVERSATIONS:
break;
case SMS_ALL_ID:
extraWhere = "_id=" + url.getPathSegments().get(0);
break;
case SMS_INBOX_ID:
case SMS_FAILED_ID:
case SMS_SENT_ID:
case SMS_DRAFT_ID:
case SMS_OUTBOX_ID:
extraWhere = "_id=" + url.getPathSegments().get(1);
break;
case SMS_CONVERSATIONS_ID: {
String threadId = url.getPathSegments().get(1);
try {
Integer.parseInt(threadId);
} catch (Exception ex) {
Log.e(TAG, "Bad conversation thread id: " + threadId);
break;
}
extraWhere = "thread_id=" + threadId;
break;
}
case SMS_STATUS_ID:
extraWhere = "_id=" + url.getPathSegments().get(1);
break;
default:
throw new UnsupportedOperationException(
"URI " + url + " not supported");
}
where = DatabaseUtils.concatenateWhere(where, extraWhere);
count = db.update(table, values, where, whereArgs);
if (count > 0) {
notifyChange(url);
}
return count;
| private android.database.Cursor | withSimNotificationUri(android.database.Cursor cursor)
cursor.setNotificationUri(getContext().getContentResolver(),
SIM_URI);
return cursor;
|
|