編輯:系統備份
這個圖片演示了這樣一種功能,首先在DDMS中向模擬器中發幾條短信,然後運行我們的程序,點擊備份,提示備份成功後,將所有的短信刪除,然後在我們的程序中點擊恢復,打開短信界面發現剛才刪除的短信已經恢復,這就是我們要實現的功能
首先來分析一下怎麼實現上述效果,如果想備份短信,首先要做的就是獲取短信的列表,這一步比較簡單因為谷歌已經將其封裝好,我們所要做的就是用Uri去查詢短信庫,就O了,然後拿到數據後需要將數據以XML的形式保存到SD卡裡面,當然你用其它的方式也可以,只要能將其恢復就行。最後恢復的時候將指定路徑的XML文件解析,根據Uri將解析的短信數據插入到系統的短信列表中。思路就是這樣一個思路。沒有看懂沒關系,下面會有源碼以及對它們的分析。 了解了大概思路後,另一個重要的任務就是看看短信的表結構在模擬器中它的路徑是data->data->com.android.providers.telephony->databases下,如下圖
將其導出然後用Sqlite數據打開可以看到數據的結構如下,這裡只關心threads表和sms表就夠了
threads表的結構如下
其中
_id:用於區分不同的電話號碼,系統會為不同的電話號碼分配不同的_id。
date:收到信息的時間(如果收到來自同一個phone number多條信息,並且有對於一條信息未讀,那麼date表示收到的最後一條信息時的時間)
message_count:收到的信息的數目
read: 0.代表未讀。1.代表已讀
對於其它字段一般很少用到,這裡就不多做介紹了,
sms表的結構如下
其中
_id:用於區分不同的短信
date:該條短信接收的時間
read: 0表未讀,1表已讀
body:表示具體的短信內容 到這裡准備工作還差一步就可以進行代碼的書寫了,哪一步呢?就是訪問這個數據庫的Uri,對於訪問手機短信的Uri主要有以下這麼幾個 content://sms/ 所有短信
/**
* 獲取短信列表
* @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文件中它是一行這裡為了讓大家更清楚的看清結構,我手動將其改成上述格式了。
保存到本地後,工作就剩下最後一步了,那就是將這個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文件已經讀完,此時所備份的短信就全部恢復了。
好了今天這篇文章就到這裡了,如果發現文章中的錯誤,歡迎指出,如果有疑問請留言,謝謝。如果你覺的本篇文章對你有幫助,就贊一下,頂一個呗,謝謝您的支持。
安卓手機短信怎麼備份
1.打開百度雲,點擊窗口界面的右上方下拉菜單中的“設置”一項 2.你會看到許多實用的手機雲端備份功能,其中就有我們需要的短信備份
安卓手機數據備份微信備份那些事
手機使用一段時候後,在手機端會保留一些對個人來說比較珍貴的數據,比如通訊錄、照片、短信、錄音等等,通常的刷機一般不會將這些數據清除掉(通訊錄會),其他的數據都
安卓系統怎麼刪除備份的系統 安卓手機刪除備份系統辦法
安卓系統怎麼刪除備份的系統?很多時候,小伙伴的一些照片或者視頻不想被系統備份,但是又沒辦法。那麼,下面一起看看刪除備份的方法.這裡需要強調的是刪除備份系統需
安卓手機數據備份功能介紹 微信如何備份資料
安卓手機數據備份的是非常重要的,尤其是對於一些要刷機的用戶來說,這個數據備份可以防止文件的丟失,下面就一起來看看這