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表的操作了。
总的来说对短信的操作还是挺简单的,复杂点的就是需要考虑提升从表中读取数据的效率。