Android 實現短信的備份恢復

jopen 12年前發布 | 70K 次閱讀 Android Android開發 移動開發

1.短信備份

package com.su.smsbackuprestore.operatesms;

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 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() + "/SMSBackup";
    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;
}

}</pre>2.短信恢復

package com.su.smsbackuprestore.operatesms;

import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List;

import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException;

import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Environment; import android.os.Looper; import android.util.Log; import android.util.Xml; import android.widget.Toast;

public class ImportSms {

private Context context;

private List<SmsItem> smsItems;
private ContentResolver conResolver;

public ImportSms(Context context) {
    this.context = context;
    conResolver = context.getContentResolver();
}

@SuppressWarnings("unchecked")
public void testInsertSMS() {
    /**
     * 放一個解析xml文件的模塊
     */
    smsItems = this.getSmsItemsFromXml();
    Log.d("sqk", "after smsItems");
    for (SmsItem item : smsItems) {

        // 判斷短信數據庫中是否已包含該條短信,如果有,則不需要恢復
        Cursor cursor = conResolver.query(Uri.parse("content://sms"), new String[] { SmsField.DATE }, SmsField.DATE + "=?",
                new String[] { item.getDate() }, null);

        if (!cursor.moveToFirst()) {// 沒有該條短信

            ContentValues values = new ContentValues();
            values.put(SmsField.ADDRESS, item.getAddress());
            // 如果是空字符串說明原來的值是null,所以這里還原為null存入數據庫
            values.put(SmsField.PERSON, item.getPerson().equals("") ? null : item.getPerson());
            values.put(SmsField.DATE, item.getDate());
            values.put(SmsField.PROTOCOL, item.getProtocol().equals("") ? null : item.getProtocol());
            values.put(SmsField.READ, item.getRead());
            values.put(SmsField.STATUS, item.getStatus());
            values.put(SmsField.TYPE, item.getType());
            values.put(SmsField.REPLY_PATH_PRESENT, item.getReply_path_present().equals("") ? null : item.getReply_path_present());
            values.put(SmsField.BODY, item.getBody());
            values.put(SmsField.LOCKED, item.getLocked());
            values.put(SmsField.ERROR_CODE, item.getError_code());
            values.put(SmsField.SEEN, item.getSeen());
            conResolver.insert(Uri.parse("content://sms"), values);
        }
        cursor.close();
    }
}

// public void delete() { // // conResolver.delete(Uri.parse("content://sms"), null, null); // }

public List<SmsItem> getSmsItemsFromXml(){

    SmsItem smsItem = null;
    XmlPullParser parser = Xml.newPullParser();
    String absolutePath = Environment.getExternalStorageDirectory() + "/SMSBackup/message.xml";
    File file = new File(absolutePath);
    if (!file.exists()) {

        Looper.prepare();
        Toast.makeText(context, "message.xml短信備份文件不在sd卡中", 1).show();
        Looper.loop();//退出線程

// return null; } try { FileInputStream fis = new FileInputStream(file); parser.setInput(fis, "UTF-8"); int event = parser.getEventType(); while (event != XmlPullParser.END_DOCUMENT) { switch (event) { case XmlPullParser.START_DOCUMENT: smsItems = new ArrayList<SmsItem>(); break;

            case XmlPullParser.START_TAG: // 如果遇到開始標記,如<smsItems>,<smsItem>等
                if ("item".equals(parser.getName())) {
                    smsItem = new SmsItem();

                    smsItem.setAddress(parser.getAttributeValue(0));
                    smsItem.setPerson(parser.getAttributeValue(1));
                    smsItem.setDate(parser.getAttributeValue(2));
                    smsItem.setProtocol(parser.getAttributeValue(3));
                    smsItem.setRead(parser.getAttributeValue(4));
                    smsItem.setStatus(parser.getAttributeValue(5));
                    smsItem.setType(parser.getAttributeValue(6));
                    smsItem.setReply_path_present(parser.getAttributeValue(7));
                    smsItem.setBody(parser.getAttributeValue(8));
                    smsItem.setLocked(parser.getAttributeValue(9));
                    smsItem.setError_code(parser.getAttributeValue(10));
                    smsItem.setSeen(parser.getAttributeValue(11));

                }
                break;
            case XmlPullParser.END_TAG:// 結束標記,如</smsItems>,</smsItem>等
                if ("item".equals(parser.getName())) {
                    smsItems.add(smsItem);
                    smsItem = null;
                }
                break;
            }
            event = parser.next();
        }
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        Looper.prepare();
        Toast.makeText(context, "短信恢復出錯", 1).show();
        Looper.loop();
        e.printStackTrace();

    } catch (XmlPullParserException e) {
        // TODO Auto-generated catch block
        Looper.prepare();
        Toast.makeText(context, "短信恢復出錯", 1).show();
        Looper.loop();
        e.printStackTrace();        

    } catch (IOException e) {
        // TODO Auto-generated catch block
        Looper.prepare();
        Toast.makeText(context, "短信恢復出錯", 1).show();
        Looper.loop();
        e.printStackTrace();
    }
    return smsItems;
}

}</pre>3.輔助

package com.su.smsbackuprestore.operatesms;

public class SmsField {

public static final String ADDRESS = "address";
public static final String PERSON = "person";
public static final String DATE = "date";
public static final String PROTOCOL = "protocol";
public static final String READ = "read";
public static final String STATUS = "status";
public static final String TYPE = "type";
public static final String REPLY_PATH_PRESENT = "reply_path_present";
public static final String BODY = "body";
public static final String LOCKED = "locked";
public static final String ERROR_CODE = "error_code";
public static final String SEEN = "seen";

}</pre>

package com.su.smsbackuprestore.operatesms;

public class SmsItem { 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;

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

public String getPerson() {
    return person;
}

public void setPerson(String person) {
    this.person = person;
}

public String getDate() {
    return date;
}

public void setDate(String date) {
    this.date = date;
}

public String getProtocol() {
    return protocol;
}

public void setProtocol(String protocol) {
    this.protocol = protocol;
}

public String getRead() {
    return read;
}

public void setRead(String read) {
    this.read = read;
}

public String getStatus() {
    return status;
}

public void setStatus(String status) {
    this.status = status;
}

public String getType() {
    return type;
}

public void setType(String type) {
    this.type = type;
}

public String getReply_path_present() {
    return reply_path_present;
}

public void setReply_path_present(String reply_path_present) {
    this.reply_path_present = reply_path_present;
}

public String getBody() {
    return body;
}

public void setBody(String body) {
    this.body = body;
}

public String getLocked() {
    return locked;
}

public void setLocked(String locked) {
    this.locked = locked;
}

public String getError_code() {
    return error_code;
}

public void setError_code(String error_code) {
    this.error_code = error_code;
}

public String getSeen() {
    return seen;
}

public void setSeen(String seen) {
    this.seen = seen;
}

}</pre>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!