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)学习笔记247:ContentProvider使用之利用ContentProvider备份和还原手机短信(掌握)的更多相关文章

  1. Android(java)学习笔记191: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. MongoDB 复制集模式Replica Sets

    1.概述 复制集是一个带有故障转移的主从集群.是从现有的主从模式演变而来,增加了自动故障转移和节点成员自动恢复. 复制集模式中没有固定的主结点,在启动后,多个服务节点间将自动选举 产生一个主结点.该主 ...

  2. Code::Blocks 的配色方案

    codeblocks的配置文件是default.conf, 在Windows系统下,该文件在C:\Documents and Settings\Administrator\Application Da ...

  3. function field , store={}...

    def _get_product_state(self,cr,uid,ids,fields,arg=None,context=None): res={} dic=dict( self.pool.get ...

  4. protocol(协议) 和 delegate(委托)也叫(代理)---辨析

    protocol和delegate完全不是一回事. 协议(protocol),(名词)要求.就是使用了这个协议后就要按照这个协议来办事,协议要求实现的方法就一定要实现. 委托(delegate),(动 ...

  5. 安装 mysql server

    三个月前向公司申请了一台服务器单独给我用,作为部署我写的自动发布工具的服务器.同事不久前在我这台服务器上装了个数据库,今天上去查了一下,用不了,只有information_schema和test两个数 ...

  6. Java中的多线程总结(转)

      1.多线程概述 当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程.主要以下几个优点: 线程之间很容易实现共享内存 创建线程代价较小 Java语言内置多线程功能支持 2.线 ...

  7. 【Unity探究】物理碰撞实验

    这几天为了准备面试,所以决定对平时学习中的盲点扫盲一下,首先想到的就是物理碰撞.以前没有好好研究过,一直模糊不清,到底什么条件下才可以产生物理碰撞呢?只要其中一个有Rigidbody就可以了吗?所以进 ...

  8. jQuery.dialog

    本篇文章主要是对JQUERY中dialog的用法进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助 今天用到了客户端的对话框,把 jQuery UI 中的对话框学习了一下. 准备 jQ ...

  9. STM8S 模拟I2C程序

    STM8S的硬件I2C还是存在问题,不敢贸然使用. 于是决定用模拟I2C. #define SCL PE_ODR_ODR1 #define SDA PE_ODR_ODR2 #define SDAM P ...

  10. Android Wear开发 - 数据通讯 - 第四节 : 数据封装(解决不能序列化问题)

    一. 前言 背景 一开始笔者在研究数据发送与接收的时候,看到Wear数据类DataMap除了可以put基本类型外,还有个fromBundle方法来构建一个DataMap对象.所以一口气的将原本功能上的 ...