1. 通过阅读系统源码我们知道:

短信的内容提供者:

content://sms/            系统短信的内容提供者的路径

2. 利用ContentProvider备份和还原手机短信:

(1)新建一个Android工程,命名为"短信备份助手",如下:

(2)我们先实现UI布局,activity_main.xml,如下:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.himi.smsbackup.MainActivity" > <Button
android:onClick="smsBackup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="备份" />
<Button
android:onClick="smsRestores"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="还原" /> </LinearLayout>

布局效果如下:

(3)编写MainActivity,如下:

 package com.himi.smsbackup;

 import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer; import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Xml;
import android.view.View;
import android.widget.Toast; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} /**
* 短信备份
* @param view
*/
public void smsBackup(View view) {
try {
// 系统短信数据库是私有的,不能访问,只能使用内容提供者ContentProvider去访问
ContentResolver resolver = getContentResolver();
// 指定Uri
Uri uri = Uri.parse("content://sms/");
Cursor cursor = resolver.query(uri, new String[] { "address",
"date", "type", "body" }, null, null, null);
// 存储为xml文件,跨平台
// 获取一个xml的序列化器serializer
XmlSerializer serializer = Xml.newSerializer();
// 初始化设置xml序列化器serializer
File file = new File(Environment.getExternalStorageDirectory(),
"backup.xml");
FileOutputStream os = new FileOutputStream(file);
serializer.setOutput(os, "utf-8"); // 写xml文件的头
serializer.startDocument("utf-8", true);
serializer.startTag(null, "root");
while (cursor.moveToNext()) {
serializer.startTag(null, "sms"); serializer.startTag(null, "address");
String address = cursor.getString(0);
serializer.text(address);
serializer.endTag(null, "address"); serializer.startTag(null, "date");
String date = cursor.getString(1);
serializer.text(date);
serializer.endTag(null, "date"); serializer.startTag(null, "type");
String type = cursor.getString(2);
serializer.text(type);
serializer.endTag(null, "type"); serializer.startTag(null, "body");
String body = cursor.getString(3);
serializer.text(body);
serializer.endTag(null, "body"); serializer.endTag(null, "sms");
}
cursor.close();
serializer.endTag(null, "root");
serializer.endDocument();
os.close();
Toast.makeText(this, "备份成功", 0).show();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
Toast.makeText(this, "备份失败", 0).show();
}
} /**
* 还原用户的备份的短信数据
* 还原之前要提醒用户是否要覆盖旧的数据
* @param view
*/
public void smsRestores(View view) {
File file = new File(Environment.getExternalStorageDirectory(),
"backup.xml");
//file.lastModified();获取文件上一次备份时间
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("提醒");
builder.setMessage("是否清除旧的短信?");
builder.setPositiveButton("确实清除", new OnClickListener() { public void onClick(DialogInterface dialog, int which) {
Uri uri = Uri.parse("content://sms/");
getContentResolver().delete(uri, null, null);
restore(); }
});
builder.setNegativeButton("不清楚数据", new OnClickListener() { public void onClick(DialogInterface dialog, int which) {
restore(); }
}); builder.show();
} public void restore() {
try { File file = new File(Environment.getExternalStorageDirectory(),
"backup.xml");
FileInputStream is = new FileInputStream(file);
//获取xml的pull解析器
XmlPullParser parser = Xml.newPullParser();
//初始化设置xml的pull解析器
parser.setInput(is, "utf-8");
int type = parser.getEventType(); String address = null;
String date = null;
String smstype = null;
String body = null;
while(type != XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_TAG:
//开始解析标签
if("address".equals(parser.getName())) {
address = parser.nextText();
}else if ("date".equals(parser.getName())){
date = parser.nextText();
}else if ("type".equals(parser.getName())){
smstype = parser.nextText();
}else if ("body".equals(parser.getName())){
body = parser.nextText();
} break; case XmlPullParser.END_TAG:
if ("sms".equals(parser.getName())) {
// 结束解析标签,把短信的数据加入到系统短信应用数据库中
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://sms/");
ContentValues values = new ContentValues();
values.put("address", address);
values.put("date", date);
values.put("type", smstype);
values.put("body", body);
resolver.insert(uri, values);
}
break;
}
type = parser.next();//指向下一待解析的标签
}
Toast.makeText(this, "还原成功", 0).show();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
Toast.makeText(this, "还原失败", 0).show();
} }
}

上面使用到要存取数据到SD卡,要添加相应的权限。同时读取系统短信应用也需要相应的权限,AndroidMainfest.xml,如下:

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.himi.smsbackup"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>

(4)布署程序到模拟器上,如下:

•我们先在模拟器上模拟发送和接收几条短信,如下:

•回到上面我们编写的应用程序中,点击"备份",提示备份成功,如下:

•查看Sd保存路径,如下图,导出这个backup.xml文件到桌面,然后使用IE打开这个backup.xml文件,如下:

•这个时候,我们去删除模拟器上的短信,如下:

•回到编写的应用程序中,点击"还原",如下:

•回到系统短信页面,看到:

Android(java)学习笔记191:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)的更多相关文章

  1. Android(java)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)

    1.通过阅读系统源码我们知道: 短信的内容提供者: content://sms/            系统短信的内容提供者的路径 2. 利用ContentProvider备份和还原手机短信: (1) ...

  2. [知了堂学习笔记]_Java代码实现MySQL数据库的备份与还原

    通常在MySQL数据库的备份和恢复的时候,多是采用在cmd中执行mysql命令来实现. 例如: mysqldump -h127.0.0.1 -uroot -ppass test > d:/tes ...

  3. 0028 Java学习笔记-面向对象-Lambda表达式

    匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...

  4. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

  5. Android动画学习笔记-Android Animation

    Android动画学习笔记-Android Animation   3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...

  6. Java学习笔记:语言基础

    Java学习笔记:语言基础 2014-1-31   最近开始学习Java,目的倒不在于想深入的掌握Java开发,而是想了解Java的基本语法,可以阅读Java源代码,从而拓展一些知识面.同时为学习An ...

  7. Android 数字签名学习笔记

    Android 数字签名学习笔记 在Android系统中,所有安装到系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系,如果一个permission的pro ...

  8. 【Java学习笔记之二十六】深入理解Java匿名内部类

    在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意 ...

  9. 20145316许心远《Java学习笔记(第8版)》课程总结

    20145316许心远<Java学习笔记(第8版)>课程总结 每周读书笔记链接汇总 ▪ 第一周读书笔记 ▪ 第二周读书笔记 ▪ 第三周读书笔记 ▪ 第四周读书笔记 ▪ 第五周读书笔记 ▪ ...

随机推荐

  1. mongodb07---用户权限

    用户管理: 注意: 添加用户后,我们再次退出并登陆,发现依然可以直接读数据库? 原因: mongodb服务器启动时, 默认不是需要认证的. 要让用户生效, 需要启动服务器时,就指定 --auth 选项 ...

  2. Atom vim mode

    /******************************************************************** * Atom vim mode * 说明: * 想找一个具有 ...

  3. 小程序 video 层级,原生组件

    原生组件的层级是最高的,所以页面中的其他组件无论设置 z-index 为多少,都无法盖在原生组件上. 后插入的原生组件可以覆盖之前的原生组件. 原生组件还无法在 scroll-view.swiper. ...

  4. springboot(十)SpringBoot消息中间件RabbitMQ

    github地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service 1. ...

  5. pyinstaller打包.py程序为.exe操作指南

    pyinstaller打包.py程序为.exe操作指南 20190526内容纲要: 1.pyinstaller安装 2.程序封装 3.可执行程序 0 前言 今天第一次试试将一个py程序封装成一个.ex ...

  6. Xposed 集成 Android 6.0.1环境中,总结

    由于工作需要,需要将xposed集成到android源码中,生成新的ROM就自带xposed的功能. 下面大体上说一下步骤和遇到的问题. 1.下载,并编译android源码,成功. 2.下载 http ...

  7. the "ssl" parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx.conf

    一:开始Nginx的SSL模块 1.1 Nginx如果未开启SSL模块,配置Https时提示错误 原因也很简单,nginx缺少http_ssl_module模块,编译安装的时候带上--with-htt ...

  8. [POI2008]激光发射器SZK

    Description 多边形相邻边垂直,边长为整数,边平行坐标轴.要在多边形的点上放一些激光发射器和接收器.满足下列要求: 1发射器和接收器不能放置在同一点: 2发射器发出激光可以沿壁反射,最终到达 ...

  9. 2018年全国多校算法寒假训练营练习比赛(第五场):A题:逆序数(树状数组or归并排序)

    题目描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数.比如一个序列为4 5 1 3 2, 那么这个序列 ...

  10. synchronized(1)用法简介:修饰方法,修饰语句块

    注意: 同一个对象或方法在不同线程中才出现同步问题,不同对象在不同线程互相不干扰. synchronized方法有2种用法:修饰方法,修饰语句块 1.synchronized方法 是某个对象实例内,s ...