参考:
http://gnibre.iteye.com/blog/558031
http://www.cnblogs.com/qinglong1983/
http://jackyear.is-programmer.com/
短信 sms
文件 /data/data/com.android.providers.telephony/databases/mmssms.db这个数据库有13张表,sms表存了短信信息。
短信收件箱对应的URI是content://sms/inbox
很简单吧,就是sms短信,然后inbox收件箱,类似,短信里面的URI分别是
content://sms/
content://sms/inbox
content://sms/sent
content://sms/draft
content://sms/outbox
content://sms/failed
content://sms/queued
android.provider.Telephony:
- /**
- *ThethreadIDofthemessage
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringTHREAD_ID="thread_id";
- /**
- *Theaddressoftheotherparty
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringADDRESS="address";
- /**
- *ThepersonIDofthesender
- *<P>Type:INTEGER(long)</P>
- */
- publicstaticfinalStringPERSON_ID="person";
- /**
- *Thedatethemessagewassent
- *<P>Type:INTEGER(long)</P>
- */
- publicstaticfinalStringDATE="date";
- /**
- *Theprotocolidentifiercode
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringPROTOCOL="protocol";
- /**
- *Hasthemessagebeenread
- *<P>Type:INTEGER(boolean)</P>
- */
- publicstaticfinalStringREAD="read";
- /**
- *TheTP-Statusvalueforthemessage,or-1ifnostatushas
- *beenreceived
- */
- publicstaticfinalStringSTATUS="status";
- us举例:
- publicstaticfinalintSTATUS_NONE=-1;
- publicstaticfinalintSTATUS_COMPLETE=0;
- publicstaticfinalintSTATUS_PENDING=64;
- publicstaticfinalintSTATUS_FAILED=128;
- /**
- *Thetypeofthemessage
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringTYPE="type";
- 举例
- publicstaticfinalintMESSAGE_TYPE_ALL=0;
- publicstaticfinalintMESSAGE_TYPE_INBOX=1;
- publicstaticfinalintMESSAGE_TYPE_SENT=2;
- publicstaticfinalintMESSAGE_TYPE_DRAFT=3;
- publicstaticfinalintMESSAGE_TYPE_OUTBOX=4;
- publicstaticfinalintMESSAGE_TYPE_FAILED=5;//forfailedoutgoingmessages
- publicstaticfinalintMESSAGE_TYPE_QUEUED=6;//formessagestosendlater
- /**
- *Whetherthe<code>TP-Reply-Path</code>bitwassetonthismessage
- *<P>Type:BOOLEAN</P>
- */
- publicstaticfinalStringREPLY_PATH_PRESENT="reply_path_present";
- /**
- *Thesubjectofthemessage,ifpresent
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringSUBJECT="subject";
- /**
- *Thebodyofthemessage
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringBODY="body";
- /**
- *Theservicecenter(SC)throughwhichtosendthemessage,ifpresent
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringSERVICE_CENTER="service_center";
- /**
- *Hasthemessagebeenlocked?
- *<P>Type:INTEGER(boolean)</P>
- */
- publicstaticfinalStringLOCKED="locked";
- **
- *Theidofthesenderoftheconversation,ifpresent
- *<P>Type:INTEGER(referencetoitemincontent://contacts/people)</P>
- */
- publicstaticfinalStringPERSON="person";
thread_id 序号,同一发信人的id相同
address 发件人手机号码
person 联系人列表里的序号,陌生人为null (不稳定无法获取联系人ID)
date 发件日期
protocol 协议,分为: 0 SMS_RPOTO, 1 MMS_PROTO
read 是否阅读 0未读, 1已读
status 状态 -1接收,0 complete, 64 pending, 128 failed
type
ALL = 0;
INBOX = 1;
SENT = 2;
DRAFT = 3;
OUTBOX = 4;
FAILED = 5;
QUEUED = 6;
body 短信内容
service_center 短信服务中心号码编号
subject 短信的主题
reply_path_present TP-Reply-Path
locked
Url中content://sms 替换成content://sms/ 也成功,但是其它url时程序报错,比如content://sms/inbox
看了一下android的源代码,sms支持的协议有:
sURLMatcher.addURI("sms", null, SMS_ALL);
sURLMatcher.addURI("sms", "#", SMS_ALL_ID);
sURLMatcher.addURI("sms", "inbox", SMS_INBOX);
sURLMatcher.addURI("sms", "inbox/#", SMS_INBOX_ID);
sURLMatcher.addURI("sms", "sent", SMS_SENT);
sURLMatcher.addURI("sms", "sent/#", SMS_SENT_ID);
sURLMatcher.addURI("sms", "draft", SMS_DRAFT);
sURLMatcher.addURI("sms", "draft/#", SMS_DRAFT_ID);
sURLMatcher.addURI("sms", "outbox", SMS_OUTBOX);
sURLMatcher.addURI("sms", "outbox/#", SMS_OUTBOX_ID);
sURLMatcher.addURI("sms", "undelivered", SMS_UNDELIVERED);
sURLMatcher.addURI("sms", "failed", SMS_FAILED);
sURLMatcher.addURI("sms", "failed/#", SMS_FAILED_ID);
sURLMatcher.addURI("sms", "queued", SMS_QUEUED);
sURLMatcher.addURI("sms", "conversations", SMS_CONVERSATIONS);
sURLMatcher.addURI("sms", "conversations/*", SMS_CONVERSATIONS_ID);
sURLMatcher.addURI("sms", "raw", SMS_RAW_MESSAGE);
sURLMatcher.addURI("sms", "attachments", SMS_ATTACHMENT);
sURLMatcher.addURI("sms", "attachments/#", SMS_ATTACHMENT_ID);
sURLMatcher.addURI("sms", "threadID", SMS_NEW_THREAD_ID);
sURLMatcher.addURI("sms", "threadID/*", SMS_QUERY_THREAD_ID);
sURLMatcher.addURI("sms", "status/#", SMS_STATUS_ID);
sURLMatcher.addURI("sms", "sr_pending", SMS_STATUS_PENDING);
sURLMatcher.addURI("sms", "sim", SMS_ALL_SIM);
sURLMatcher.addURI("sms", "sim/#", SMS_SIM);
--------------------------------------------------------------------------------
其中,delete方法中支持的协议为:
SMS_ALL 根据参数中的条件删除sms表数据
SMS_ALL_ID 根据_id删除sms表数据
SMS_CONVERSATIONS_ID 根据thread_id删除sms表数据,可以带其它条件
SMS_RAW_MESSAGE 根据参数中的条件删除 raw表
SMS_STATUS_PENDING 根据参数中的条件删除 sr_pending表
SMS_SIM 从Sim卡上删除数据
试一下SMS_CONVERSATIONS_ID:"
在eclipse中的Emulator Control中,以13800给模拟器发送三条数据,然后以13900发送一条
this.getContentResolver().delete(Uri.parse("content://sms/conversations/3"), "_id=?", new String[]{"5"});
成功删除一条数据。
在数据库中每个发送者的thread_id虽然一样,但不是固定的,如果把一个发送者的全部数据删除掉,
然后换一个新号码发送短信时,thread_id是以数据库中最大的id+1赋值的。
--------------------------------------------------------------------------------
update支持的协议有很多:
SMS_RAW_MESSAGE
SMS_STATUS_PENDING
SMS_ALL
SMS_FAILED
SMS_QUEUED
SMS_INBOX
SMS_SENT
SMS_DRAFT
SMS_OUTBOX
SMS_CONVERSATIONS
SMS_ALL_ID
SMS_INBOX_ID
SMS_FAILED_ID
SMS_SENT_ID
SMS_DRAFT_ID
SMS_OUTBOX_ID
SMS_CONVERSATIONS_ID
SMS_STATUS_ID
以SMS_INBOX_ID测试一下:
ContentValues cv = new ContentValues();
cv.put("thread_id", "2");
cv.put("address", "00000");
cv.put("person", "11");
cv.put("date", "11111111");
this.getContentResolver().update(Uri.parse("content://sms/inbox/4"), cv, null, null);
太强了,连thread_id都可以修改。
--------------------------------------------------------------------------------
insert支持的协议:
SMS_ALL
SMS_INBOX
SMS_FAILED
SMS_QUEUED
SMS_SENT
SMS_DRAFT
SMS_OUTBOX
SMS_RAW_MESSAGE
SMS_STATUS_PENDING
SMS_ATTACHMENT
SMS_NEW_THREAD_ID
向sms表插入数据时,type是根据协议来自动设置,
如果传入的数据中没有设置date时,自动设置为当前系统时间;非SMS_INBOX协议时,read标志设置为1
SMS_INBOX协议时,系统会自动查询并设置PERSON
threadId为null或者0时,系统也会自动设置
一直为造不了"发送失败"的邮件而发愁,现在来做一个:
content://sms/failed
ContentValues cv = new ContentValues();
cv.put("_id", "99");
cv.put("thread_id", "0");
cv.put("address", "9999");
cv.put("person", "888");
cv.put("date", "9999");
cv.put("protocol", "0");
cv.put("read", "1");
cv.put("status", "-1");
//cv.put("type", "0");
cv.put("body", "@@@@@@@@@");
this.getContentResolver().insert(Uri.parse("content://sms/failed"), cv);
type被设置成了5,thread_id设置为1
彩信。
1、pdu表
mmssms.db库中的pdu表存储了彩信标题、彩信接收时间和彩信ID等信息,其中“_id”是主键,唯一标识了一个条彩信。
- /**
- *BasecolumnsfortablesthatcontainMMSs.
- */
- publicinterfaceBaseMmsColumnsextendsBaseColumns{
- publicstaticfinalintMESSAGE_BOX_ALL=0;
- publicstaticfinalintMESSAGE_BOX_INBOX=1;
- publicstaticfinalintMESSAGE_BOX_SENT=2;
- publicstaticfinalintMESSAGE_BOX_DRAFTS=3;
- publicstaticfinalintMESSAGE_BOX_OUTBOX=4;
- /**
- *Thedatethemessagewassent.
- *<P>Type:INTEGER(long)</P>
- */
- publicstaticfinalStringDATE="date";
- /**
- *Theboxwhichthemessagebelongto,forexample,MESSAGE_BOX_INBOX.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringMESSAGE_BOX="msg_box";
- /**
- *Hasthemessagebeenread.
- *<P>Type:INTEGER(boolean)</P>
- */
- publicstaticfinalStringREAD="read";
- /**
- *TheMessage-IDofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringMESSAGE_ID="m_id";
- /**
- *Thesubjectofthemessage,ifpresent.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringSUBJECT="sub";
- /**
- *Thecharactersetofthesubject,ifpresent.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringSUBJECT_CHARSET="sub_cs";
- /**
- *TheContent-Typeofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringCONTENT_TYPE="ct_t";
- /**
- *TheContent-Locationofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringCONTENT_LOCATION="ct_l";
- /**
- *Theaddressofthesender.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringFROM="from";
- /**
- *Theaddressoftherecipients.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringTO="to";
- /**
- *Theaddressofthecc.recipients.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringCC="cc";
- /**
- *Theaddressofthebcc.recipients.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringBCC="bcc";
- /**
- *Theexpirytimeofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringEXPIRY="exp";
- /**
- *Theclassofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringMESSAGE_CLASS="m_cls";
- /**
- *ThetypeofthemessagedefinedbyMMSspec.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringMESSAGE_TYPE="m_type";
- /**
- *Theversionofspecificationthatthismessageconform.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringMMS_VERSION="v";
- /**
- *Thesizeofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringMESSAGE_SIZE="m_size";
- /**
- *Thepriorityofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringPRIORITY="pri";
- /**
- *Theread-reportofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringREAD_REPORT="rr";
- /**
- *Whetherthereportisallowed.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringREPORT_ALLOWED="rpt_a";
- /**
- *Theresponse-statusofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringRESPONSE_STATUS="resp_st";
- /**
- *Thestatusofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringSTATUS="st";
- /**
- *Thetransaction-idofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringTRANSACTION_ID="tr_id";
- /**
- *Theretrieve-statusofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringRETRIEVE_STATUS="retr_st";
- /**
- *Theretrieve-textofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringRETRIEVE_TEXT="retr_txt";
- /**
- *Thecharactersetoftheretrieve-text.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringRETRIEVE_TEXT_CHARSET="retr_txt_cs";
- /**
- *Theread-statusofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringREAD_STATUS="read_status";
- /**
- *Thecontent-classofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringCONTENT_CLASS="ct_cls";
- /**
- *Thedelivery-reportofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringDELIVERY_REPORT="d_rpt";
- /**
- *Thedelivery-time-tokenofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringDELIVERY_TIME_TOKEN="d_tm_tok";
- /**
- *Thedelivery-timeofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringDELIVERY_TIME="d_tm";
- /**
- *Theresponse-textofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringRESPONSE_TEXT="resp_txt";
- /**
- *Thesender-visibilityofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringSENDER_VISIBILITY="s_vis";
- /**
- *Thereply-chargingofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringREPLY_CHARGING="r_chg";
- /**
- *Thereply-charging-deadline-tokenofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringREPLY_CHARGING_DEADLINE_TOKEN="r_chg_dl_tok";
- /**
- *Thereply-charging-deadlineofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringREPLY_CHARGING_DEADLINE="r_chg_dl";
- /**
- *Thereply-charging-idofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringREPLY_CHARGING_ID="r_chg_id";
- /**
- *Thereply-charging-sizeofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringREPLY_CHARGING_SIZE="r_chg_sz";
- /**
- *Thepreviously-sent-byofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringPREVIOUSLY_SENT_BY="p_s_by";
- /**
- *Thepreviously-sent-dateofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringPREVIOUSLY_SENT_DATE="p_s_d";
- /**
- *Thestoreofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringSTORE="store";
- /**
- *Themm-stateofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringMM_STATE="mm_st";
- /**
- *Themm-flags-tokenofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringMM_FLAGS_TOKEN="mm_flg_tok";
- /**
- *Themm-flagsofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringMM_FLAGS="mm_flg";
- /**
- *Thestore-statusofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringSTORE_STATUS="store_st";
- /**
- *Thestore-status-textofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringSTORE_STATUS_TEXT="store_st_txt";
- /**
- *Thestoredofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringSTORED="stored";
- /**
- *Thetotalsofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringTOTALS="totals";
- /**
- *Thembox-totalsofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringMBOX_TOTALS="mb_t";
- /**
- *Thembox-totals-tokenofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringMBOX_TOTALS_TOKEN="mb_t_tok";
- /**
- *Thequotasofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringQUOTAS="qt";
- /**
- *Thembox-quotasofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringMBOX_QUOTAS="mb_qt";
- /**
- *Thembox-quotas-tokenofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringMBOX_QUOTAS_TOKEN="mb_qt_tok";
- /**
- *Themessage-countofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringMESSAGE_COUNT="m_cnt";
- /**
- *Thestartofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringSTART="start";
- /**
- *Thedistribution-indicatorofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringDISTRIBUTION_INDICATOR="d_ind";
- /**
- *Theelement-descriptorofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringELEMENT_DESCRIPTOR="e_des";
- /**
- *Thelimitofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringLIMIT="limit";
- /**
- *Therecommended-retrieval-modeofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringRECOMMENDED_RETRIEVAL_MODE="r_r_mod";
- /**
- *Therecommended-retrieval-mode-textofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringRECOMMENDED_RETRIEVAL_MODE_TEXT="r_r_mod_txt";
- /**
- *Thestatus-textofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringSTATUS_TEXT="st_txt";
- /**
- *Theapplic-idofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringAPPLIC_ID="apl_id";
- /**
- *Thereply-applic-idofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringREPLY_APPLIC_ID="r_apl_id";
- /**
- *Theaux-applic-idofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringAUX_APPLIC_ID="aux_apl_id";
- /**
- *Thedrm-contentofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringDRM_CONTENT="drm_c";
- /**
- *Theadaptation-allowedofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringADAPTATION_ALLOWED="adp_a";
- /**
- *Thereplace-idofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringREPLACE_ID="repl_id";
- /**
- *Thecancel-idofthemessage.
- *<P>Type:TEXT</P>
- */
- publicstaticfinalStringCANCEL_ID="cl_id";
- /**
- *Thecancel-statusofthemessage.
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringCANCEL_STATUS="cl_st";
- /**
- *ThethreadIDofthemessage
- *<P>Type:INTEGER</P>
- */
- publicstaticfinalStringTHREAD_ID="thread_id";
- /**
- *Hasthemessagebeenlocked?
- *<P>Type:INTEGER(boolean)</P>
- */
- publicstaticfinalStringLOCKED="locked";
- }
2、part表
mmssms.db库中的part表存储了彩信内容(文本、音乐、图象)的文件名(即上面将的app_parts下面的文件名)、文件类型信息。
其中“mid”对应着pdu表中的“_id”,“ct”是文件类型,“_data”是存储路径。
3 。 彩信文件读取
彩信附件文件的地址存储在mmssms.db的part表的_data字段,形如“/data/data/com.android.providers.telephony/app_parts/PART_1262693697763”,但在应用中读取彩信附件时,这个字段基本没什么用,因为不能直接读取这个文件。读取同样要通过ContentProvider,URI为“content://mms/part”,该URI就是对应着part表。可以使用下列代码段来读取文件:
String selection = new String("mid='" + key + "'");//这个key就是pdu里面的_id。
Cursor cur = getContentResolver().query(Uri.parse("content://mms/part"), null, selection, null, null);
if (cur.moveToFirst())
do {
int _partID = cur.getInt(cur.getColumnIndex("_id"));
String partID = String.valueOf(_partID);
Uri partURI = Uri.parse("content://mms/part/" + partID);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = null;
try {
is = getContentResolver().openInputStream(partURI);
byte[] buffer = new byte[256];
int len = is.read(buffer);
while (len >= 0)
{
baos.write(buffer, 0, len);
len = is.read(buffer);
}
} catch (IOException e) {
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
}
}
这里得到的baos,就是附件文件。