轉載請注明出處:http://blog.csdn.net/l1028386804/article/details/47091281
眼下,Android手機中的一些軟件能夠實現手機短信的備份與還原操作。這篇博文就是要向大家介紹怎樣實現Android短信的備份與還原操作。好了。相信大家對這些有用的功能還是比較感興趣的,不多說了。我們直接進入主題吧。
一、原理
我的實現原理非常easy,界面上放置幾個TextView列表,當中兩項為“短信的備份”和“短信的還原”。點擊“短信的備份”,讀取全部的短信信息,將短信信息保存在一個xml文件里,這個xml文件放置的sdcard中。作為短信的備份文件,然后當須要還原短信的時候。僅僅須要點擊“短信的還原”。這時程序首先會刪除手機上現有的短信,然后從短信的備份xml文件里讀取之前備份的短信內容。寫入手機短信數據庫中。
原理講完了。是不是非常easy呢?以下,我們就一起來實現這些功能吧。
二、實踐
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;
}
@Override
public 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 stub
this.context = context;
}
//得到全部的短信
public List<SmsInfo> getSmsInfos(){
List<SmsInfo> smsInfos = new ArrayList<SmsInfo>();
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<SmsInfo> 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");
//address
serializer.startTag(null, "address");
serializer.text(info.getAddress());
serializer.endTag(null, "address");
//date
serializer.startTag(null, "date");
serializer.text(info.getDate());
serializer.endTag(null, "date");
//type
serializer.startTag(null, "type");
serializer.text(info.getType());
serializer.endTag(null, "type");
//body
serializer.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<SmsInfo> getSmsInfosFromXml() throws Exception{
List<SmsInfo> 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<SmsInfo>();
}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;
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
smsInfoService = new SmsInfoService(this);
nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
new Thread(){
public void run() {
//1 得到全部的短信
//2 生成一個xml文件
List<SmsInfo> 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 block
e.printStackTrace();
//looper是一個消息泵,從消息隊列(MessageQueue)里面抽取消息,把消息交給Handler處理
Looper.prepare();
Toast.makeText(getApplicationContext(), "短信備份失敗", 0).show();
Looper.loop();
}
stopSelf();//停止服務
};
}.start();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
4、布局實現
詳細實現代碼例如以下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView style="@style/text_title_style" android:text="高級工具" /> <View style="@style/view_divide_line_style"/> <TextView android:id="@+id/tv_atools_add_ipcall" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="加入ip撥號" android:textColor="@android:color/white" android:textSize="20sp" android:paddingTop="10dp" android:paddingBottom="10dp"/> <include layout="@layout/line"/> <TextView android:id="@+id/tv_atools_address_query" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="號碼歸屬地查詢" android:textColor="@android:color/white" android:textSize="20sp" android:paddingTop="10dp" android:paddingBottom="10dp"/> <include layout="@layout/line"/> <TextView android:id="@+id/tv_atools_sms_backup" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="短信備份" android:textColor="@android:color/white" android:textSize="20sp" android:paddingTop="10dp" android:paddingBottom="10dp"/> <include layout="@layout/line"/> <TextView android:id="@+id/tv_atools_sms_restore" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="短信的還原" android:textColor="@android:color/white" android:textSize="20sp" android:paddingTop="10dp" android:paddingBottom="10dp"/> <include layout="@layout/line"/> </LinearLayout>
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;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.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 stub
int 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<SmsInfo> 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 block
e.printStackTrace();
mPd.dismiss();
Looper.prepare();
Toast.makeText(getApplicationContext(), "短信還原失敗", 1).show();
Looper.loop();
}
};
}.start();
}
}
6、加入權限
別忘了向AndroidManifest.xml文件注冊對應的權限
詳細例如以下:
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_SMS"/> <uses-permission android:name="android.permission.WRITE_SMS"/>
三、執行效果
執行界面

短信備份完成

通知顯示

開始還原短信

正在還原短信

短信還原成功

四、溫馨提示
本實例中,為了方面,我把一些文字直接寫在了布局文件里和相關的類中,大家在真實的項目中要把這些文字寫在string.xml文件里。在外部引用這些資源,切記,這是作為一個Android程序猿最主要的開發常識和規范,我在這里僅僅是為了方便直接寫在了類和布局文件里。
