最近在做一個Android 備份軟件,剛剛把短信的備份與恢復做完。短信的備份主要是對數據庫mmssms.db的sms表進行數據的導出,當然這裡是跨應用的,所以要使用contendResolver來訪問,最後把數據導出成xml文件。恢復時再對xml文件解析。備份時注意,不要備份thread_id字段,否則恢復時,手機中查看不到恢復的短信。
源代碼下載在Linux公社的1號FTP服務器裡,下載地址:
FTP地址:ftp://www.linuxidc.com
用戶名:www.linuxidc.com
密碼:www.muu.cc
在 2011年LinuxIDC.com\10月\10月\Android 短信的備份與恢復(導入導出)
下載方法見 http://www.linuxidc.net/thread-1187-1-1.html
短信導出源碼:
- package cn.sqk.sms;
-
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.PrintWriter;
- import java.text.SimpleDateFormat;
- import java.util.Date;
-
- import org.dom4j.Document;
- import org.dom4j.DocumentHelper;
- import org.dom4j.Element;
- import org.xmlpull.v1.XmlSerializer;
-
- import cn.sqk.constants.SmsField;
-
- import android.content.ContentResolver;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteException;
- import android.net.Uri;
- import android.os.Environment;
- import android.util.Log;
- import android.util.Xml;
- import android.widget.Toast;
-
- public class ExportSmsXml {
- Context context;
- public static final String SMS_URI_ALL = "content://sms/";
- private FileOutputStream outStream = null;
- private XmlSerializer serializer;
-
- public ExportSmsXml(Context context) {
- this.context = context;
- }
-
- public void xmlStart() {
-
- String path = Environment.getExternalStorageDirectory().getPath() + "/exportSms";
- File file = new File(path);
- if (!file.exists()) {
- file.mkdirs();
- }
- File file2 = new File(path, "message.xml");
- try {
- outStream = new FileOutputStream(file2);
- serializer = Xml.newSerializer();
- serializer.setOutput(outStream, "UTF-8");
- serializer.startDocument("UTF-8", true);
- serializer.startTag(null, "sms");
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public boolean createXml() throws Exception {
-
- this.xmlStart();
- Cursor cursor = null;
- try {
- ContentResolver conResolver = context.getContentResolver();
- String[] projection = new String[] { SmsField.ADDRESS, SmsField.PERSON, SmsField.DATE, SmsField.PROTOCOL,
- SmsField.READ, SmsField.STATUS, SmsField.TYPE, SmsField.REPLY_PATH_PRESENT,
- SmsField.BODY,SmsField.LOCKED,SmsField.ERROR_CODE, SmsField.SEEN }; // type=1是收件箱,==2是發件箱;read=0表示未讀,read=1表示讀過,seen=0表示未讀,seen=1表示讀過
- Uri uri = Uri.parse(SMS_URI_ALL);
- cursor = conResolver.query(uri, projection, null, null, "_id asc");
- if (cursor.moveToFirst()) {
- // 查看數據庫sms表得知 subject和service_center始終是null所以這裡就不獲取它們的數據了。
- String address;
- String person;
- String date;
- String protocol;
- String read;
- String status;
- String type;
- String reply_path_present;
- String body;
- String locked;
- String error_code;
- String seen;
- do {
- // 如果address == null,xml文件中是不會生成該屬性的,為了保證解析時,屬性能夠根據索引一一對應,必須要保證所有的item標記的屬性數量和順序是一致的
- address = cursor.getString(cursor.getColumnIndex(SmsField.ADDRESS));
- if (address == null) {
- address = "";
- }
- person = cursor.getString(cursor.getColumnIndex(SmsField.PERSON));
- if (person == null) {
- person = "";
- }
- date = cursor.getString(cursor.getColumnIndex(SmsField.DATE));
- if (date == null) {
- date = "";
- }
- protocol = cursor.getString(cursor.getColumnIndex(SmsField.PROTOCOL));
- if (protocol == null) {// 為了便於xml解析
- protocol = "";
- }
- read = cursor.getString(cursor.getColumnIndex(SmsField.READ));
- if (read == null) {
- read = "";
- }
- status = cursor.getString(cursor.getColumnIndex(SmsField.STATUS));
- if (status == null) {
- status = "";
- }
- type = cursor.getString(cursor.getColumnIndex(SmsField.TYPE));
- if (type == null) {
- type = "";
- }
- reply_path_present = cursor.getString(cursor.getColumnIndex(SmsField.REPLY_PATH_PRESENT));
- if (reply_path_present == null) {// 為了便於XML解析
- reply_path_present = "";
- }
- body = cursor.getString(cursor.getColumnIndex(SmsField.BODY));
- if (body == null) {
- body = "";
- }
- locked = cursor.getString(cursor.getColumnIndex(SmsField.LOCKED));
- if (locked == null) {
- locked = "";
- }
- error_code = cursor.getString(cursor.getColumnIndex(SmsField.ERROR_CODE));
- if (error_code == null) {
- error_code = "";
- }
- seen = cursor.getString(cursor.getColumnIndex(SmsField.SEEN));
- if (seen == null) {
- seen = "";
- }
- // 生成xml子標記
- // 開始標記
- serializer.startTag(null, "item");
- // 加入屬性
- serializer.attribute(null, SmsField.ADDRESS, address);
- serializer.attribute(null, SmsField.PERSON, person);
- serializer.attribute(null, SmsField.DATE, date);
- serializer.attribute(null, SmsField.PROTOCOL, protocol);
- serializer.attribute(null, SmsField.READ, read);
- serializer.attribute(null, SmsField.STATUS, status);
- serializer.attribute(null, SmsField.TYPE, type);
- serializer.attribute(null, SmsField.REPLY_PATH_PRESENT, reply_path_present);
- serializer.attribute(null, SmsField.BODY, body);
- serializer.attribute(null, SmsField.LOCKED, locked);
- serializer.attribute(null, SmsField.ERROR_CODE, error_code);
- serializer.attribute(null, SmsField.SEEN, seen);
- // 結束標記
- serializer.endTag(null, "item");
-
- } while (cursor.moveToNext());
- } else {
-
- return false;
- }
-
- } catch (SQLiteException ex) {
- ex.printStackTrace();
- Log.d("SQLiteException:", ex.getMessage());
- }finally {
- if(cursor != null) {
- cursor.close();//手動關閉cursor,及時回收
- }
- }
- serializer.endTag(null, "sms");
- serializer.endDocument();
- outStream.flush();
- outStream.close();
- return true;
- }
- }