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

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

短信的内容提供者:

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

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

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

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

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical"
 6     tools:context="com.himi.smsbackup.MainActivity" >
 7 
 8     <Button
 9         android:onClick="smsBackup"
10         android:layout_width="match_parent"
11         android:layout_height="wrap_content"
12         android:text="备份" />
13      <Button
14         android:onClick="smsRestores"
15         android:layout_width="match_parent"
16         android:layout_height="wrap_content"
17         android:text="还原" />
18 
19 </LinearLayout>

布局效果如下:

(3)编写MainActivity,如下:

  1 package com.himi.smsbackup;
  2 
  3 import java.io.File;
  4 import java.io.FileInputStream;
  5 import java.io.FileOutputStream;
  6 
  7 import org.xmlpull.v1.XmlPullParser;
  8 import org.xmlpull.v1.XmlSerializer;
  9 
 10 import android.app.Activity;
 11 import android.app.AlertDialog;
 12 import android.app.AlertDialog.Builder;
 13 import android.content.ContentResolver;
 14 import android.content.ContentValues;
 15 import android.content.DialogInterface;
 16 import android.content.DialogInterface.OnClickListener;
 17 import android.database.Cursor;
 18 import android.net.Uri;
 19 import android.os.Bundle;
 20 import android.os.Environment;
 21 import android.util.Xml;
 22 import android.view.View;
 23 import android.widget.Toast;
 24 
 25 public class MainActivity extends Activity {
 26 
 27     @Override
 28     protected void onCreate(Bundle savedInstanceState) {
 29         super.onCreate(savedInstanceState);
 30         setContentView(R.layout.activity_main);
 31     }
 32    
 33     
 34    /**
 35     * 短信备份    
 36     * @param view
 37     */
 38     public void smsBackup(View view) {
 39         try {
 40             // 系统短信数据库是私有的,不能访问,只能使用内容提供者ContentProvider去访问
 41             ContentResolver resolver = getContentResolver();
 42             // 指定Uri
 43             Uri uri = Uri.parse("content://sms/");
 44             Cursor cursor = resolver.query(uri, new String[] { "address",
 45                     "date", "type", "body" }, null, null, null);
 46             // 存储为xml文件,跨平台
 47             // 获取一个xml的序列化器serializer
 48             XmlSerializer serializer = Xml.newSerializer();
 49             // 初始化设置xml序列化器serializer
 50             File file = new File(Environment.getExternalStorageDirectory(),
 51                     "backup.xml");
 52             FileOutputStream os = new FileOutputStream(file);
 53             serializer.setOutput(os, "utf-8");
 54 
 55             // 写xml文件的头
 56             serializer.startDocument("utf-8", true);
 57             serializer.startTag(null, "root");
 58             while (cursor.moveToNext()) {
 59                 serializer.startTag(null, "sms");
 60 
 61                 serializer.startTag(null, "address");
 62                 String address = cursor.getString(0);
 63                 serializer.text(address);
 64                 serializer.endTag(null, "address");
 65 
 66                 serializer.startTag(null, "date");
 67                 String date = cursor.getString(1);
 68                 serializer.text(date);
 69                 serializer.endTag(null, "date");
 70 
 71                 serializer.startTag(null, "type");
 72                 String type = cursor.getString(2);
 73                 serializer.text(type);
 74                 serializer.endTag(null, "type");
 75 
 76                 serializer.startTag(null, "body");
 77                 String body = cursor.getString(3);
 78                 serializer.text(body);
 79                 serializer.endTag(null, "body");
 80 
 81                 serializer.endTag(null, "sms");
 82             }
 83             cursor.close();
 84             serializer.endTag(null, "root");
 85             serializer.endDocument();
 86             os.close();
 87             Toast.makeText(this, "备份成功", 0).show();
 88         } catch (Exception e) {
 89             // TODO 自动生成的 catch 块
 90             e.printStackTrace();
 91             Toast.makeText(this, "备份失败", 0).show();
 92         }
 93     }
 94     
 95     /**
 96      * 还原用户的备份的短信数据
 97      *         还原之前要提醒用户是否要覆盖旧的数据
 98      * @param view
 99      */
100     public void smsRestores(View view) {
101         File file = new File(Environment.getExternalStorageDirectory(),
102                 "backup.xml");
103         //file.lastModified();获取文件上一次备份时间
104         AlertDialog.Builder builder = new Builder(this);
105         builder.setTitle("提醒");
106         builder.setMessage("是否清除旧的短信?");
107         builder.setPositiveButton("确实清除", new OnClickListener() {
108             
109             public void onClick(DialogInterface dialog, int which) {
110                 Uri uri = Uri.parse("content://sms/");
111                 getContentResolver().delete(uri, null, null);
112                 restore();
113                 
114             }
115         });
116         builder.setNegativeButton("不清楚数据", new OnClickListener() {
117             
118             public void onClick(DialogInterface dialog, int which) {
119                 restore();
120                 
121             }
122         });
123         
124         builder.show();
125     }
126     
127     public void restore() {
128         try {
129             
130             File file = new File(Environment.getExternalStorageDirectory(),
131                     "backup.xml");
132             FileInputStream  is = new FileInputStream(file);
133             //获取xml的pull解析器
134             XmlPullParser parser = Xml.newPullParser();
135             //初始化设置xml的pull解析器
136             parser.setInput(is, "utf-8");
137             int type = parser.getEventType();
138             
139             String address = null;
140             String date = null;
141             String smstype = null;
142             String body = null;
143             while(type != XmlPullParser.END_DOCUMENT) {
144                 switch (type) {
145                 case XmlPullParser.START_TAG:
146                     //开始解析标签
147                     if("address".equals(parser.getName())) {
148                         address = parser.nextText();
149                     }else if ("date".equals(parser.getName())){
150                         date = parser.nextText();
151                     }else if ("type".equals(parser.getName())){
152                         smstype = parser.nextText();
153                     }else if ("body".equals(parser.getName())){
154                         body = parser.nextText();
155                     }
156                     
157                     break;
158 
159                 case XmlPullParser.END_TAG:
160                     if ("sms".equals(parser.getName())) {
161                         // 结束解析标签,把短信的数据加入到系统短信应用数据库中
162                         ContentResolver resolver = getContentResolver();
163                         Uri uri = Uri.parse("content://sms/");
164                         ContentValues values = new ContentValues();
165                         values.put("address", address);
166                         values.put("date", date);
167                         values.put("type", smstype);
168                         values.put("body", body);
169                         resolver.insert(uri, values);
170                     }
171                     break;
172                 }
173                 type = parser.next();//指向下一待解析的标签
174             }
175             Toast.makeText(this, "还原成功", 0).show();
176         } catch (Exception e) {
177             // TODO 自动生成的 catch 块
178             e.printStackTrace();
179             Toast.makeText(this, "还原失败", 0).show();
180         }
181         
182     }
183 }

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

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="com.himi.smsbackup"
 4     android:versionCode="1"
 5     android:versionName="1.0" >
 6 
 7     <uses-sdk
 8         android:minSdkVersion="15"
 9         android:targetSdkVersion="17" />
10     <uses-permission android:name="android.permission.READ_SMS"/>
11     <uses-permission android:name="android.permission.WRITE_SMS"/>
12     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
13 
14     <application
15         android:allowBackup="true"
16         android:icon="@drawable/ic_launcher"
17         android:label="@string/app_name"
18         android:theme="@style/AppTheme" >
19         <activity
20             android:name=".MainActivity"
21             android:label="@string/app_name" >
22             <intent-filter>
23                 <action android:name="android.intent.action.MAIN" />
24 
25                 <category android:name="android.intent.category.LAUNCHER" />
26             </intent-filter>
27         </activity>
28     </application>
29 
30 </manifest>

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

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

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

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

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

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

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

原文地址:https://www.cnblogs.com/hebao0514/p/4807605.html