相关文章:Android开发之内容提供者——创建自己的ContentProvider(详解)
忍耐和坚持虽是痛苦的事情,但却能渐渐地为你带来好处.——奥维德。
这个图片演示了这样一种功能,首先在DDMS中向模拟器中发几条短信,然后运行我们的程序,点击备份,提示备份成功后,将所有的短信删除,然后在我们的程序中点击恢复,打开短信界面发现刚才删除的短信已经恢复,这就是我们要实现的功能
date: 该条短信接收的时间
read: 0表未读,1表已读
/**
* 获取短信列表
* @return
*/
public List getSmsList() {
//获取所有短信的 Uri
Uri uri = Uri. parse( "content://sms/");
//获取ContentResolver对象
ContentResolver contentResolver = mContext.getContentResolver();
//根据Uri 查询短信数据
Cursor cursor = contentResolver.query(uri, null, null, null, null);
if ( null != cursor) {
Log. i( TAG, "cursor.getCount():" + cursor.getCount());
//根据得到的Cursor一条一条的添加到smsList(短信列表)中
while (cursor.moveToNext()) {
int _id = cursor.getInt(cursor.getColumnIndex("_id" ));
int type = cursor.getInt(cursor.getColumnIndex("type" ));
String address = cursor.getString(cursor.getColumnIndex( "address"));
String body = cursor.getString(cursor.getColumnIndex("body" ));
String date = cursor.getString(cursor.getColumnIndex("date" ));
SmsData smsData = new SmsData(_id, type, address, body, date);
smsList.add(smsData);
}
cursor.close();
}
return smsList;
}
可以看到上述代码就是根据
content://sms/这个Uri去查询手机中短信的数据库,得到一个Cursor这个Cursor就包含了一条一条的短信。然后去遍历这个Cursor将我们需要的数据添加到smsList中。这样短信数据就拿到了,因为我们做的功能是短信备份,所以接下来需要将smsList这个集合中的数据保存到本地,以方便短信恢复的时候去读取保存的这个文件,那么问题来了,怎样将smsList这个集合以文件的形式保存到本地呢?当然方法有很多,这里我们采用的是使用XmlSerializer将其序列化,待我们需要恢复的时候使用XmlPullParser
将其反序列化,就可以拿到备份的数据,听起来感觉挺高大上的,其实很简单就是对xml的操作。下面来看看序列化的代码即将上面得到的集合smsList中的数据生成一个xml文件,并保存到本地,代码如下/**
* 将短信数据保存到 sd卡中
*/
public void saveSmsToSdCard(){
smsList=getSmsList();
//获得一个序列化对象
XmlSerializer xmlSerializer=Xml. newSerializer();
//将生成的 xml文件保存到sd 卡中名字为"sms.xml"
File file= new File(Environment.getExternalStorageDirectory(), "sms.xml");
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
xmlSerializer.setOutput(fos, "utf-8");
xmlSerializer.startDocument( "utf-8", true);
xmlSerializer.startTag( null, "smss");
xmlSerializer.startTag( null, "count");
xmlSerializer.text( smsList.size()+ "");
xmlSerializer.endTag( null, "count");
for(SmsData smsData: smsList){
xmlSerializer.startTag( null, "sms");
xmlSerializer.startTag( null, "_id");
xmlSerializer.text(smsData.get_id()+ "");
System. out.println( "smsData.get_id()=" +smsData.get_id());
xmlSerializer.endTag( null, "_id");
xmlSerializer.startTag( null, "type");
xmlSerializer.text(smsData.getType()+ "");
System. out.println( "smsData.getType=" +smsData.getType());
xmlSerializer.endTag( null, "type");
xmlSerializer.startTag( null, "address");
xmlSerializer.text(smsData.getAddress()+ "");
System. out.println( "smsData.getAddress()=" +smsData.getAddress());
xmlSerializer.endTag( null, "address");
xmlSerializer.startTag( null, "body");
xmlSerializer.text(smsData.getBody()+ "");
System. out.println( "smsData.getBody()=" +smsData.getBody());
xmlSerializer.endTag( null, "body");
xmlSerializer.startTag( null, "date");
xmlSerializer.text(smsData.getDate()+ "");
System. out.println( "smsData.getDate()=" +smsData.getDate());
xmlSerializer.endTag( null, "date");
xmlSerializer.endTag( null, "sms");
}
xmlSerializer.endTag( null, "smss");
xmlSerializer.endDocument();
fos.flush();
fos.close();
Toast. makeText( mContext, "备份完成", Toast.LENGTH_SHORT ).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
通过调用以上方法就将短信以xml的形式保存到了本地。运行这个方法后可以再sd卡中看到sms.xml文件,将其导出来可以看到它的格式如下
/**
* 将指定路径的 xml文件中的数据插入到短信数据库中
* @param path
*/
public void restoreSms(String path) {
File file = new File(path);
//得到一个解析 xml的对象
XmlPullParser parser = Xml. newPullParser();
try {
fis = new FileInputStream(file);
parser.setInput( fis, "utf-8");
ContentValues values = null;
int type = parser.getEventType();
while (type != XmlPullParser. END_DOCUMENT) {
switch (type) {
case XmlPullParser. START_TAG:
if ( "count".equals(parser.getName())) {
} else if ("sms" .equals(parser.getName())) {
values = new ContentValues();
} else if ("type" .equals(parser.getName())) {
values.put( "type", parser.nextText());
} else if ("address" .equals(parser.getName())) {
values.put( "address", parser.nextText());
} else if ("body" .equals(parser.getName())) {
values.put( "body", parser.nextText());
} else if ("date" .equals(parser.getName())) {
values.put( "date", parser.nextText());
}
break;
case XmlPullParser. END_TAG:
if ( "sms".equals(parser.getName())) {// 如果节点是 sms
Uri uri = Uri.parse( "content://sms/");
ContentResolver resolver = mContext.getContentResolver();
resolver.insert(uri, values);//向数据库中插入数据
System. out.println( "插入成功" );
values = null; //
}
break;
}
type=parser.next();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
可以看到在上述方法中判断xml的END_TAG是不是"sms"如果是的话说明一条短信的"type"、"address"、"body"、"date"这些信息已经拿到,然后就根据Uri将这条数据插入到数据库中,就完成一条短信的恢复,待读到 END_DOCUMENT说明xml文件已经读完,此时所备份的短信就全部恢复了。