Android中的簡訊並沒有正式的content provider可用,在官方文檔中沒有提供定義。不過依然可以自己定義好URI,然後查詢出簡訊內容。例如conetent://sms則是所有簡訊所在的path。
要將簡訊按會話分類,原先我是查詢出所有簡訊後,然後再按照thread_id分類。系統內建的簡訊程式包含一個會話顯示介面,每個條目包含:連絡人、簡訊數量、第一條簡訊等內容。當我的程式處理的簡訊較多時,一次查詢出所有的簡訊就變得很慢。(如果再加上為每個會話查詢連絡人資訊,則會更慢)
看了系統簡訊的代碼,發現它可以只查詢出會話的資訊,而不用查詢出所有簡訊內容。因為部分代碼沒找到,一直不知道它是怎麼做到的。看了telphony provider的代碼後,才知曉一二。
實際上,簡訊資料庫中(mmssms.db)並沒有一個表格儲存體會話資訊的。系統提供的content provider中,實際上是支援直接查詢會話資訊的。只不過,其實現方式,不是通過一個現成的表,而是通過SQL語句,從多個表裡取資料完成的。關於這個實現方式,在這個文章中也有所提及。
實現方式就不深究了,畢竟我對SQL查詢不太熟。放出直接的使用方法:
擷取會話資訊的URI
Java代碼
public static final Uri MMSSMS_FULL_CONVERSATION_URI = Uri.parse("content://mms-sms/conversations");
public static final Uri CONVERSATION_URI = MMSSMS_FULL_CONVERSATION_URI.buildUpon().
appendQueryParameter("simple", "true").build();
public static final Uri MMSSMS_FULL_CONVERSATION_URI = Uri.parse("content://mms-sms/conversations");
public static final Uri CONVERSATION_URI = MMSSMS_FULL_CONVERSATION_URI.buildUpon().
appendQueryParameter("simple", "true").build();
通過指定simple=true,則可以擷取出一個大概的會話資料,包含以下列:
Java代碼
private static final int ID = 0;
private static final int DATE = 1;
private static final int MESSAGE_COUNT = 2;
private static final int RECIPIENT_IDS = 3;
private static final int SNIPPET = 4;
private static final int SNIPPET_CS = 5;
private static final int READ = 6;
private static final int TYPE = 7;
private static final int ERROR = 8;
private static final int HAS_ATTACHMENT = 9;
列名則為:
Java代碼
private static final String[] ALL_THREADS_PROJECTION = {
"_id", "date", "message_count", "recipient_ids",
"snippet", "snippet_cs", "read", "error", "has_attachment"
};
其中:
1、message_count為該會話的訊息數量;
2、recipient_ids為連絡人ID,這個ID不是連絡人表中的_id,而是指向表 canonical_addresses 裡的id,canonical_addresses這個表同樣位於mmssms.db,它映射了recipient_ids到一個電話號碼,也就是說,最終擷取連絡人資訊,還是得通過電話號碼;
3、snippet為最後收到/發送的簡訊;
每個資料的類型嘛,大致為:
Java代碼
long id = cursor.getLong(ID);
long date = cursor.getLong(DATE);
long msgCount = cursor.getLong(MESSAGE_COUNT);
String recipIDs = cursor.getString(RECIPIENT_IDS);
String snippet = cursor.getString(SNIPPET);
long snippetCS = cursor.getLong(SNIPPET_CS);
long read = cursor.getLong(READ);
long type = cursor.getLong(TYPE);
long error = cursor.getLong(ERROR);
long hasAttach = cursor.getLong(HAS_ATTACHMENT);
long id = cursor.getLong(ID);
long date = cursor.getLong(DATE);
long msgCount = cursor.getLong(MESSAGE_COUNT);
String recipIDs = cursor.getString(RECIPIENT_IDS);
String snippet = cursor.getString(SNIPPET);
long snippetCS = cursor.getLong(SNIPPET_CS);
long read = cursor.getLong(READ);
long type = cursor.getLong(TYPE);
long error = cursor.getLong(ERROR);
long hasAttach = cursor.getLong(HAS_ATTACHMENT);