Android(java)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)

1. 通过阅读系统源码我们知道:

短信的内容提供者:

content://sms/            系统短信的内容提供者的路径

2. 利用ContentProvider备份和还原手机短信:

(1)新建一个Android工程,命名为"短信备份助手",如下:

Android(java)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)

(2)我们先实现UI布局,activity_main.xml,如下:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.himi.smsbackup.MainActivity" > <Button
android:onClick="smsBackup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="备份" />
<Button
android:onClick="smsRestores"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="还原" /> </LinearLayout>

布局效果如下:

Android(java)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)

(3)编写MainActivity,如下:

 package com.himi.smsbackup;

 import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer; import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Xml;
import android.view.View;
import android.widget.Toast; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} /**
* 短信备份
* @param view
*/
public void smsBackup(View view) {
try {
// 系统短信数据库是私有的,不能访问,只能使用内容提供者ContentProvider去访问
ContentResolver resolver = getContentResolver();
// 指定Uri
Uri uri = Uri.parse("content://sms/");
Cursor cursor = resolver.query(uri, new String[] { "address",
"date", "type", "body" }, null, null, null);
// 存储为xml文件,跨平台
// 获取一个xml的序列化器serializer
XmlSerializer serializer = Xml.newSerializer();
// 初始化设置xml序列化器serializer
File file = new File(Environment.getExternalStorageDirectory(),
"backup.xml");
FileOutputStream os = new FileOutputStream(file);
serializer.setOutput(os, "utf-8"); // 写xml文件的头
serializer.startDocument("utf-8", true);
serializer.startTag(null, "root");
while (cursor.moveToNext()) {
serializer.startTag(null, "sms"); serializer.startTag(null, "address");
String address = cursor.getString(0);
serializer.text(address);
serializer.endTag(null, "address"); serializer.startTag(null, "date");
String date = cursor.getString(1);
serializer.text(date);
serializer.endTag(null, "date"); serializer.startTag(null, "type");
String type = cursor.getString(2);
serializer.text(type);
serializer.endTag(null, "type"); serializer.startTag(null, "body");
String body = cursor.getString(3);
serializer.text(body);
serializer.endTag(null, "body"); serializer.endTag(null, "sms");
}
cursor.close();
serializer.endTag(null, "root");
serializer.endDocument();
os.close();
Toast.makeText(this, "备份成功", 0).show();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
Toast.makeText(this, "备份失败", 0).show();
}
} /**
* 还原用户的备份的短信数据
* 还原之前要提醒用户是否要覆盖旧的数据
* @param view
*/
public void smsRestores(View view) {
File file = new File(Environment.getExternalStorageDirectory(),
"backup.xml");
//file.lastModified();获取文件上一次备份时间
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("提醒");
builder.setMessage("是否清除旧的短信?");
builder.setPositiveButton("确实清除", new OnClickListener() { public void onClick(DialogInterface dialog, int which) {
Uri uri = Uri.parse("content://sms/");
getContentResolver().delete(uri, null, null);
restore(); }
});
builder.setNegativeButton("不清楚数据", new OnClickListener() { public void onClick(DialogInterface dialog, int which) {
restore(); }
}); builder.show();
} public void restore() {
try { File file = new File(Environment.getExternalStorageDirectory(),
"backup.xml");
FileInputStream is = new FileInputStream(file);
//获取xml的pull解析器
XmlPullParser parser = Xml.newPullParser();
//初始化设置xml的pull解析器
parser.setInput(is, "utf-8");
int type = parser.getEventType(); String address = null;
String date = null;
String smstype = null;
String body = null;
while(type != XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_TAG:
//开始解析标签
if("address".equals(parser.getName())) {
address = parser.nextText();
}else if ("date".equals(parser.getName())){
date = parser.nextText();
}else if ("type".equals(parser.getName())){
smstype = parser.nextText();
}else if ("body".equals(parser.getName())){
body = parser.nextText();
} break; case XmlPullParser.END_TAG:
if ("sms".equals(parser.getName())) {
// 结束解析标签,把短信的数据加入到系统短信应用数据库中
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://sms/");
ContentValues values = new ContentValues();
values.put("address", address);
values.put("date", date);
values.put("type", smstype);
values.put("body", body);
resolver.insert(uri, values);
}
break;
}
type = parser.next();//指向下一待解析的标签
}
Toast.makeText(this, "还原成功", 0).show();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
Toast.makeText(this, "还原失败", 0).show();
} }
}

上面使用到要存取数据到SD卡,要添加相应的权限。同时读取系统短信应用也需要相应的权限,AndroidMainfest.xml,如下:

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.himi.smsbackup"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>

(4)布署程序到模拟器上,如下:

Android(java)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)

•我们先在模拟器上模拟发送和接收几条短信,如下:

Android(java)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)

•回到上面我们编写的应用程序中,点击"备份",提示备份成功,如下:

Android(java)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)

•查看Sd保存路径,如下图,导出这个backup.xml文件到桌面,然后使用IE打开这个backup.xml文件,如下:

Android(java)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)

Android(java)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)

•这个时候,我们去删除模拟器上的短信,如下:

Android(java)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)

•回到编写的应用程序中,点击"还原",如下:

Android(java)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)

•回到系统短信页面,看到:

Android(java)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)

上一篇:ASP.NET - 锚点跳转,用于回到顶部


下一篇:Ubuntu下增加eclipse菜单图标并配置java path(解决点击图标不能启动eclipse的问题)