天天看點

Android SMS 短信操作

android的短信儲存在短信庫裡,但并提供類似Contacts的公開的Content Provider友善操作。這裡簡單的介紹下:android中的短信資訊儲存在/data/data/com.android.providers.telephony/databases目錄下的sqlite庫中。常用的表有:canonical_addresses, sms, threads。對短信的操作基本也就是對這些表的CRUD。下面先看下這些表的結構,也可以使用sql檢視表中的内容

d:\test>adb shell
$ su
su
# cd /data/data/com.android.providers.telephony/databases
cd /data/data/com.android.providers.telephony/databases
# ls
ls
firewall.db       mmssms.db-wal     telephony.db-shm
mmssms.db         msmsms.db         telephony.db-wal
mmssms.db-shm     telephony.db      traffic.db
# sqlite3 mmssms.db
sqlite3 mmssms.db
SQLite version 3.7.2
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
.tables
addr                 pdu                  threads
android_metadata     pending_msgs         words
attachments          rate                 words_content
canonical_addresses  raw                  words_segdir
drm                  sms                  words_segments
part                 sr_pending
sqlite> .schema threads
.schema threads
CREATE TABLE threads (
_id INTEGER PRIMARY KEY,
date INTEGER DEFAULT 0,
server_date INTEGER DEFAULT 0,
message_count INTEGER DEFAULT 0,
unread_count INTEGER DEFAULT 0,
photo_id TEXT,
recipient_addresses TEXT,
recipient_names TEXT,
is_sp TEXT,
person_id TEXT,
recipient_ids TEXT,
snippet TEXT,s
nippet_cs INTEGER DEFAULT 0,
read INTEGER DEFAULT 1,
type INTEGER DEFAULT 0,
error INTEGER DEFAULT 0,
has_attachment INTEGER DEFAULT 0,
state INTEGER DEFAULT 0);
sqlite> .schema sms
.schema sms
CREATE TABLE sms (
_id INTEGER PRIMARY KEY,
thread_id INTEGER,
address TEXT,
person INTEGER,
date INTEGER,
server_date INTEGER,
protocol INTEGER,
read INTEGER DEFAULT 0,
status INTEGER DEFAULT -1,
type INTEGER,
reply_path_present INTEGER,
subject TEXT,
body TEXT,
service_center TEXT,
locked INTEGER DEFAULT 0,
error_code INTEGER DEFAULT 0,
seen INTEGER DEFAULT 0,
timed INTEGER DEFAULT 0);
           

(這裡需要注意的是檢視/data/data目錄下的檔案需要有root權限)

sms表中的主要字段介紹:

_id             短消息序号    

thread_id       關聯threads表中的id,對話的序号    

address         發件人位址,手機号

person          發件人,傳回一個數字就是聯系人清單裡的序号

date            日期  long型   

protocol        協定 0 SMS_RPOTO, 1 MMS_PROTO    

read            是否閱讀 0未讀, 1已讀    

status          狀态 -1接收,0 complete, 64 pending, 128 failed    

type            類型 1是接收到的,2是已發出    

body            短消息内容    

service_center  短信服務中心号碼編号 

// 讀取收件箱中指定号碼的短信
Cursor cursor = managedQuery(Uri.parse("content://sms/inbox"),
		new String[] { "_id", "address", "body", "read" }, " address=? and read=?", new String[] { "106597281",
				"0" }, "date desc");
if (cursor != null) {
	ContentValues values = new ContentValues();
	values.put("read", "1");
	// 修改短信為已讀模式
	cursor.moveToFirst();
	if (cursor.moveToFirst()) {
		// 根據id修改短信的狀态為已讀狀态
		getContentResolver().update(Uri.parse("content://sms/inbox"), values, " _id=?",
				new String[] { "" + cursor.getInt(0) });
		// 删除指定号碼的短信
		int smsId = cursor.getInt(0);
		String msgbody = cursor.getString(cursor.getColumnIndexOrThrow("body"));
		try {
			msgbody = (new String(msgbody.getBytes(), "utf8")).trim();
		} catch (UnsupportedEncodingException e) {
			Log.e("TAG", "", e);
		}
		// 删除指定短信
		getContentResolver().delete(Uri.parse("content://sms/" + smsId), null, null);
	}
}
cursor.close();
           

另外值得注意的是調用SMSManager.sendTextMessage接口發送短信是不會将資訊寫入到sms表中的,若需要記錄到表中就需要添加寫入sms表的操作了。

總的來說對短信的操作還是挺簡單的,複雜點的就是需要考慮提升從表中讀取資料的效率。