Android的短信和彩信是放在/data/data/com.android.provider.telephony/databases目录下的mmssms.db数据文件的。拿一部具有root权限的手机用sqlite工具打开可以看到里面的数据库结构,这里是sqliteadmin打开的界面:
其中threads是存放会话的数据表,sms是存放短信的数据表,pdu是存放彩信的数据表,而part就是存放彩信附件的表了。
这个表中有几个关键的字段,第一个就是mid字段,这是附件相应彩信表的id,即pdu._id = part.mid。第二个是ct表,它表示的是附件的类型,如application/smil表示的是彩信内容的布局之类的信息、text/plain表示的是文本、image/jpg表示的是jpg图片、audio/midi表示是midi声音。第三个是_data字段,它表示的是附件相对应的文件 每个附件都会有一个独立的文件,附件存放地址是/data/data/com.android.provider.telephony/databases/app_parts。第四个字段是text,它表示的是文本的内容,如果附件是文本的话,那么这个字段就会存储文本,如果是其他类型除application/smil外则没有内容。
上面有说到_data字段是附件对应的文件,但知道这个并没有用,因为没有root权限的话你是不可能取得附件的。那么就只能通过一种方式,就是通过contentprovider来获取,在得到附件的uri后,用contentResolver打开输入流来获取附件的内容。代码如下:
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就是得到的附件文件内容,这时就可以通过文件流将它写到sdcard上去保存成文件了。