Android之——簡訊的備份與還原
目前,Android手機中的一些軟體可以實現手機簡訊的備份與還原作業。這篇博文就是要向大家介紹如何?Android簡訊的備份與還原作業。好了,相信大家對這些實用的功能還是比較感興趣的,不多說了,我們直接進入主題吧。
一、原理
我的實現原理很簡單,介面上放置幾個TextView列表,其中兩項為“簡訊的備份”和“簡訊的還原”,點擊“簡訊的備份”,讀取所有的簡訊資訊,將簡訊資訊儲存在一個xml檔案中,這個xml檔案放置的sdcard中,作為簡訊的備份檔案,然後當需要還原簡訊的時候,只需要點擊“簡訊的還原”,這時程式首先會刪除手機上現有的簡訊,然後從簡訊的備份xml檔案中讀取之前備份的簡訊內容,寫入手機簡訊資料庫中。
原理講完了,是不是很簡單呢?下面,我們就一起來實現這些功能吧!
二、實踐1、建立簡訊的實體類SmsInfo
為了使程式更加物件導向化,更加符合物件導向的封裝,我將簡訊資訊封裝成了一個實體類SmsInfo
具體代碼如下:
package cn.lyz.mobilesafe.domain;/** * 簡訊內容的實體類 * @author liuyazhuang * */public class SmsInfo {//電話號碼private String address;//日期private String date;//簡訊類型private String type;//簡訊內容private String body;public SmsInfo() {super();// TODO Auto-generated constructor stub}public SmsInfo(String address, String date, String type, String body) {super();this.address = address;this.date = date;this.type = type;this.body = body;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public String getDate() {return date;}public void setDate(String date) {this.date = date;}public String getType() {return type;}public void setType(String type) {this.type = type;}public String getBody() {return body;}public void setBody(String body) {this.body = body;}@Overridepublic String toString() {return SmsInfo [address= + address + , date= + date + , type=+ type + , body= + body + ];}}
2、建立簡訊操作業務類SmsInfoService
這個類主要封裝了對簡訊資料的操作,同時封裝了對xml檔案的寫入與解析操作。備份簡訊流程是首先從簡訊資料庫中讀取簡訊,然後將簡訊資訊寫入xml檔案。還原簡訊的流程為先刪除手機中的簡訊,然後解析備份的簡訊檔案,將解析出的簡訊資訊寫入簡訊資料庫。
具體實現代碼如下:
package cn.lyz.mobilesafe.engine;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.util.ArrayList;import java.util.List;import org.xmlpull.v1.XmlPullParser;import org.xmlpull.v1.XmlSerializer;import android.content.Context;import android.database.Cursor;import android.net.Uri;import android.os.Environment;import android.util.Xml;import cn.lyz.mobilesafe.domain.SmsInfo;/** * 擷取簡訊內容的業務類 * @author liuyazhuang * */public class SmsInfoService {private Context context;public SmsInfoService(Context context) {// TODO Auto-generated constructor stubthis.context = context;}//得到所有的簡訊public List getSmsInfos(){List smsInfos = new ArrayList();Uri uri = Uri.parse(content://sms);Cursor c = context.getContentResolver().query(uri, new String[]{address,date,type,body}, null, null, null);while(c.moveToNext()){String address = c.getString(c.getColumnIndex(address));String date = c.getString(c.getColumnIndex(date));String type = c.getString(c.getColumnIndex(type));String body = c.getString(c.getColumnIndex(body));SmsInfo smsInfo = new SmsInfo(address, date, type, body);smsInfos.add(smsInfo);}return smsInfos;}//把簡訊資料寫入到xml檔案public void createXml(List smsInfos) throws Exception{XmlSerializer serializer = Xml.newSerializer();File file = new File(Environment.getExternalStorageDirectory(), smsbackup.xml);OutputStream os = new FileOutputStream(file);serializer.setOutput(os, UTF-8);serializer.startDocument(UTF-8, true);serializer.startTag(null, smsinfos);for(SmsInfo info:smsInfos){serializer.startTag(null, smsinfo);//addressserializer.startTag(null, address);serializer.text(info.getAddress());serializer.endTag(null, address);//dateserializer.startTag(null, date);serializer.text(info.getDate());serializer.endTag(null, date);//typeserializer.startTag(null, type);serializer.text(info.getType());serializer.endTag(null, type);//bodyserializer.startTag(null, body);serializer.text(info.getBody());serializer.endTag(null, body);serializer.endTag(null, smsinfo);}serializer.endTag(null, smsinfos);serializer.endDocument();os.close();}//從xml檔案中得到簡訊資料public List getSmsInfosFromXml() throws Exception{List smsInfos =null;SmsInfo smsInfo = null;XmlPullParser parser = Xml.newPullParser();File file = new File(Environment.getExternalStorageDirectory(), smsbackup.xml);InputStream inputStream = new FileInputStream(file);parser.setInput(inputStream, UTF-8);int eventType = parser.getEventType();while(eventType != XmlPullParser.END_DOCUMENT){switch (eventType) {case XmlPullParser.START_TAG:if(smsinfos.equals(parser.getName())){smsInfos = new ArrayList();}else if(smsinfo.equals(parser.getName())){smsInfo = new SmsInfo();}else if(address.equals(parser.getName())){String address = parser.nextText();smsInfo.setAddress(address);}else if(date.equals(parser.getName())){String date = parser.nextText();smsInfo.setDate(date);}else if(type.equals(parser.getName())){String type = parser.nextText();smsInfo.setType(type);}else if(body.equals(parser.getName())){String body = parser.nextText();smsInfo.setBody(body);}break;case XmlPullParser.END_TAG: if(smsinfo.equals(parser.getName())){smsInfos.add(smsInfo);smsInfo = null;}break;default:break;}eventType = parser.next();}return smsInfos;}}
3、建立備份簡訊的服務類BackupSmsService
這個類主要是實現備份簡訊的操作,將備份簡訊的操作放在一個服務類中執行,由於讀取資料庫的操作是一個耗時的操作,所以我在這個類中開啟了一個線程來做簡訊的備份操作,如果備份簡訊失敗,則提示使用者備份失敗,如果備份簡訊成功,則對外發出通知,提示使用者簡訊備份成功。操作完畢後停止服務。
具體實現代碼如下:
package cn.lyz.mobilesafe.service;import java.util.List;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.Context;import android.content.Intent;import android.os.IBinder;import android.os.Looper;import android.widget.Toast;import cn.lyz.mobilesafe.R;import cn.lyz.mobilesafe.activity.MainActivity;import cn.lyz.mobilesafe.domain.SmsInfo;import cn.lyz.mobilesafe.engine.SmsInfoService;/** * 備份簡訊的服務類 * @author liuyazhuang * */public class BackupSmsService extends Service {private SmsInfoService smsInfoService;private NotificationManager nm;@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();smsInfoService = new SmsInfoService(this);nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);new Thread(){public void run() {//1 得到所有的簡訊//2 產生一個xml檔案List smsInfos = smsInfoService.getSmsInfos();try {smsInfoService.createXml(smsInfos);//發送一個通知告訴使用者備份完成Notification notification = new Notification(R.drawable.notification, 簡訊備份完畢, System.currentTimeMillis());Intent intent = new Intent(getApplicationContext(),MainActivity.class);PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 100, intent, 0);notification.setLatestEventInfo(getApplicationContext(), 提示資訊, 簡訊備份完畢, contentIntent);//點擊通知訊息自動消失notification.flags = Notification.FLAG_AUTO_CANCEL;nm.notify(100, notification);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();//looper是一個訊息泵,從訊息佇列(MessageQueue)裡面抽取訊息,把訊息交給Handler處理Looper.prepare();Toast.makeText(getApplicationContext(), 簡訊備份失敗, 0).show();Looper.loop();}stopSelf();//停止服務};}.start();}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}}
4、布局實現
具體實現代碼如下:
5、完善Activity類
在這個類中主要完成的功能是,找到頁面上的控制項,並設定控制項的狀態事件,在相應事件中完成對業務的響應操作。
具體實現代碼如下:
package cn.lyz.mobilesafe.activity;import java.util.List;import android.app.Activity;import android.app.ProgressDialog;import android.content.ContentValues;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.os.Looper;import android.os.SystemClock;import android.view.View;import android.view.View.OnClickListener;import android.widget.TextView;import android.widget.Toast;import cn.lyz.mobilesafe.R;import cn.lyz.mobilesafe.domain.SmsInfo;import cn.lyz.mobilesafe.engine.SmsInfoService;import cn.lyz.mobilesafe.service.BackupSmsService;/** * 簡訊的備份與還原 * @author liuyazhuang * */public class AtoolsActivity extends Activity implements OnClickListener{private TextView tv_atools_sms_backup;private TextView tv_atools_sms_restore;private ProgressDialog mPd;private SmsInfoService smsInfoService;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.atools);tv_atools_sms_backup = (TextView) findViewById(R.id.tv_atools_sms_backup);tv_atools_sms_backup.setOnClickListener(this);tv_atools_sms_restore = (TextView) findViewById(R.id.tv_atools_sms_restore);tv_atools_sms_restore.setOnClickListener(this);smsInfoService = new SmsInfoService(this);}public void onClick(View v) {// TODO Auto-generated method stubint id = v.getId();Intent intent = null;switch (id) {case R.id.tv_atools_sms_backup:intent = new Intent(this,BackupSmsService.class);startService(intent);break;case R.id.tv_atools_sms_restore:restoreSms();default:break;}}/** * 還原簡訊操作 */private void restoreSms() {//1 刪除所有的簡訊//2 把xml裡面的資料插入到簡訊的資料庫 //2.1 先解析xml檔案 //2.2 插入資料mPd = new ProgressDialog(this);mPd.setTitle(正在刪除原來的簡訊);mPd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);mPd.show();new Thread(){public void run() {try {Uri uri = Uri.parse(content://sms);getContentResolver().delete(uri, null, null);mPd.setTitle(正在還原簡訊);List smsInfos = smsInfoService.getSmsInfosFromXml();mPd.setMax(smsInfos.size());for(SmsInfo smsInfo:smsInfos){ContentValues values = new ContentValues();values.put(address, smsInfo.getAddress());values.put(date, smsInfo.getDate());values.put(type, smsInfo.getType());values.put(body, smsInfo.getBody());getContentResolver().insert(uri, values);SystemClock.sleep(2000);mPd.incrementProgressBy(1);//每次進度條刻度值加1}mPd.dismiss();Looper.prepare();Toast.makeText(getApplicationContext(), 簡訊還原成功, 1).show();Looper.loop();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();mPd.dismiss();Looper.prepare();Toast.makeText(getApplicationContext(), 簡訊還原失敗, 1).show();Looper.loop();}};}.start();}}
6、添加許可權
別忘了向AndroidManifest.xml檔案註冊相應的許可權
具體如下:
三、運行效果
運行介面
簡訊備份完畢
通知顯示
開始還原簡訊
正在還原簡訊
簡訊還原成功
四、溫馨提示
本執行個體中,為了方面,我把一些文字直接寫在了布局檔案中和相關的類中,大家在真實的項目中要把這些文字寫在string.xml檔案中,在外部參考這些資源,切記,這是作為一個Android程式員最基本的開發常識和規範,我在這裡只是為了方便直接寫在了類和布局檔案中。