Android之——短信的备份与还原
转载请注明出处: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"/>
三、执行效果
执行界面
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" height="335" width="459">
短信备份完成
通知显示
開始还原短信
正在还原短信
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" height="344" width="454">
短信还原成功
四、温馨提示
本实例中,为了方面,我把一些文字直接写在了布局文件里和相关的类中,大家在真实的项目中要把这些文字写在string.xml文件里。在外部引用这些资源,切记,这是作为一个Android程序猿最主要的开发常识和规范,我在这里仅仅是为了方便直接写在了类和布局文件里。
Android之——短信的备份与还原的更多相关文章
- Android 短信的备份
接着上文<Android 内容提供者的实现>,继续实战 打开File Exploer,找到mmssms.db数据库,导出 打开mmssms.db 新建项目,布局如下: <Relati ...
- 无废话Android之listview入门,自定义的数据适配器、采用layoutInflater打气筒创建一个view对象、常用数据适配器ArrayAdapter、SimpleAdapter、使用ContentProvider(内容提供者)共享数据、短信的备份、插入一条记录到系统短信应用(3)
1.listview入门,自定义的数据适配器 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/and ...
- Android获取短信验证码
Android开发中关于短息验证码的设计层出不穷,越来越多的应用为了更好的提高软件的安全性,开始使用通过服务器向用户发送验证码的方式,来保护用户个人信息的安全性.无论是用户注册时的信息验证还是当用户发 ...
- Android接收短信
Android收到短信时会广播android.provider.Telephony.SMS_RECEIVED消息,因此只要定义一个Receiver,收听该消息,就能接收短信. <receiver ...
- android拦截短信并屏蔽系统的Notification
拦截短信有几个关键点: 1.android接收短信时是以广播的方式 2.程序只要在自己的Manifest.xml里加有"接收"SMS的权限 <uses-permission ...
- android 发送短信 怎样做到一条一条的发送,仅仅有在上一条发送成功之后才发送下一条短信
android发送短信截获上一条发送是否成功,然后再来发送下一条短信 1.问题:在项目中遇到例如以下要求:待发短信有N条,实现一条一条的发送并在上一条短信发送成功之后再来发送下一条. for(int ...
- android 发送短信的两种方式,以及接收报告和发送报告
android发送短信,以及接收报告和发送报告 android中发送短信其实有两种方式,这个和打电话类似,大家可以了解一下: 一.调起系统发短信功能 ...
- android 获取短信验证码倒计时
android 获取短信验证码倒计时 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWVuZ2xlbGUxMzE0/font/5a6L5L2T/fonts ...
- 用Tasker实现收到Android手机短信自动转发到邮箱
发送短信到邮箱的原理与 <用Tasker实现收到Android手机短信自动转发到邮箱>有些类似. 发送短信到邮箱是利用Ifttt这个服务将短信转发到邮箱中.Ifttt服务的可扩展性很强, ...
随机推荐
- BZOJ 3110 [Zjoi2013]K大数查询(整体二分)
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 11654 Solved: 3505[Submit][St ...
- Android SDK Manager代理设置
1.SDK Manager中打开 Tools—>Manage Add-on Sites…—>User Defined Sites 2.New …输入: http://android-mir ...
- 题解 P2610 【[ZJOI2012]旅游】
今天模拟赛考了这道题,那就来水一篇题解吧...(话说提高组模拟赛考什么省选题啊??) 这道题要我们求一条线段最多能经过的三角形数量. 回想小学学过的奥数,老师告诉过我们这样一件事:`点无大小 线无粗细 ...
- 题解 P2330 【[SCOI2005]繁忙的都市】
又是一道Kruskal题目. AC代码见下. 主要思路就是将所有的边储存起来,然后进行贪心地选择,期间需要判断两个端点是否有关联,这一过程通过并查集实现.Kruskal部分套模板就可以了. #incl ...
- 05001_Linux简介
1.Linux的概述 (1)Linux是基于Unix的开源免费的操作系统,由于系统的稳定性和安全性几乎成为程序代码运行的最佳系统环境.Linux是由Linus Torvalds(林纳斯•托瓦兹)起初开 ...
- 15 hbase 学习(十五)缓存机制以及可以利用SSD作为存储的BucketCache
下面介绍Hbase的缓存机制: a.HBase在读取时,会以Block为单位进行cache,用来提升读的性能 b.Block可以分类为DataBlock(默认大小64K,存储KV).BloomBlo ...
- ArcGIS api for javascript——动态创建图层列表
描述 本例循环地图服务里的所有图层并增加每个图层到一个带checkbox的列表,checkbox能设置图层的显示或隐藏.动态创建列表的优势是所有的图层都会包含在列表中,即使服务器管理员删除或增加了图层 ...
- 积跬步,聚小流------Bootstrap学习记录(2)
现阶段开启每一次新的征程,已然离不开"Hello World"的习惯仪式.这次自然也不例外.先来看下给出的官网给出的演示样例: 1.bootstrap官网提供的html基本模板代码 ...
- nodeJs学习路线
转载自:http://blog.fens.me/nodejs-roadmap/ 前言 用Nodejs已经1年有余,陆陆续续写了48篇关于Nodejs的博客文章,用过的包有上百个. 和全部人一样,我也从 ...
- poj--1459--Power Network(最大流,超级源超级汇)
Power Network Time Limit: 2000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u Submit ...