最近写程序用到了对短信的备份和恢复。 这里有几个点记录一下。
1. android 4.4 以后, 短信机制发生变换, 添加默认短信功能, 于是第三方软件无法实现短信的写操作。
2. 备份时候使用 写入 xml 文件, 因而设计xml 文件的序列化和解析, 都需要设置相应的文件对象 setInput,和 setOutput.
3. 写读取的时候, 出现ANR 现象, 原因是 while 循环里面没有对
name 和 type 这两个量实现更新。
4. 代码中, 备份部分, 添加了一个备份用的回调接口函数, 可用于UI界面回调显示更新控件
public class SmsUtils {
private static final String TAG = "SmsUtils";
private static File file;
private static File file_restore;
public interface BackupCallBack{
// 设置进度条的最大值
public void beforeBackup(int max);
// 设置进度更新
public void duringBackup(int process);
}
public static void Smsbackup(Context context,BackupCallBack callback) throws Exception{
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)){
file = new File(Environment.getExternalStorageDirectory(),"smsbackup.xml");
Log.d(TAG,"没有找到sd卡");
}
else{
file = new File(context.getFilesDir(),"smsbackup.xml");
}
FileOutputStream fos = new FileOutputStream(file);
Log.d(TAG,"创建xml序列化器");
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(fos,"utf-8");
serializer.startDocument("utf-8",true);
Log.d(TAG,"获取内容提供者数据");
ContentResolver resolver = context.getContentResolver();
Uri uri = Telephony.Sms.CONTENT_URI;
Cursor cursor = resolver.query(uri,new String[]{Sms.ADDRESS,Sms.DATE,Sms.BODY,Sms.TYPE},null,null);
serializer.startTag(null,"sms");
serializer.attribute(null,"max",cursor.getCount() + "");
callback.beforeBackup(cursor.getCount());
int process = 0;
while (cursor.moveToNext()){
serializer.startTag(null,"sms_item");
// 得到每项数据
String address = cursor.getString(0);
String date = cursor.getString(1);
String body = cursor.getString(2);
String type = cursor.getString(3);
// 地址
serializer.startTag(null,"address");
serializer.text(address);
serializer.endTag(null,"address");
// 时间
serializer.startTag(null,"date");
serializer.text(date);
serializer.endTag(null,"date");
// 内容
serializer.startTag(null,"body");
serializer.text(body);
serializer.endTag(null,"body");
// 类型
serializer.startTag(null,"type");
serializer.text(type);
serializer.endTag(null,"type");
serializer.endTag(null,"sms_item");
process++;
callback.duringBackup(process);
}
serializer.endTag(null,"sms");
serializer.endDocument();
cursor.close();
fos.close();
Log.d(TAG,"备份成功");
}
public static void SmsRestore(Context context) throws Exception{
// 找到xml文件位置
Log.d(TAG,"找到xml文件位置");
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)){
file_restore = new File(Environment.getExternalStorageDirectory(),"smsbackup.xml");
if (!file_restore.exists()){
file_restore = new File(context.getFilesDir(),"smsbackup.xml");
if (!file_restore.exists()){
//Toast.makeText(context,"没有找到备份文件",Toast.LENGTH_SHORT).show();
Log.d(TAG,"找到xml文件位置");
return;
}
}
}
Log.d(TAG,"读取文件信息");
// 读取文件信息
FileInputStream fis = new FileInputStream(file_restore);
BufferedInputStream bis = new BufferedInputStream(fis);
List<SmsEntity> list = new ArrayList<SmsEntity>();
SmsEntity entity = null;
XmlPullParser parser = Xml.newPullParser();
parser.setInput(bis,"utf-8");
int type = parser.getEventType();
int max = 0;
while (type != XmlPullParser.END_DOCUMENT){
String name = parser.getName();
switch (type){
case XmlPullParser.START_TAG:
if ("sms".equals(name)){
max = Integer.valueOf(parser.getAttributeValue(null,"max"));
}
else if ("sms_item".equals(name)){
entity = new SmsEntity();
}
else if ("address".equals(name)){
entity.setAddress(parser.nextText());
}
else if ("date".equals(name)){
entity.setDate(parser.nextText());
}
else if ("body".equals(name)){
entity.setBody(parser.nextText());
}
else if ("type".equals(name)){
entity.setType(parser.nextText());
}
break;
case XmlPullParser.END_TAG:
if ("sms_item".equals(name)){
list.add(entity);
}
break;
default:
break;
}
type = parser.next();
}
for (SmsEntity item : list){
Log.d(TAG,item.toString());
}
// 利用内容观察者, 写入短信
ContentResolver resolver = context.getContentResolver();
Uri url = Telephony.Sms.CONTENT_URI;
ContentValues values = new ContentValues();
values.put(Sms.ADDRESS,"13155158380");
values.put(Sms.DATE,"1395045035573");
values.put(Sms.BODY,"我是测试短信");
values.put(Sms.TYPE,"1");
Uri uri = resolver.insert(url,values);
//Toast.makeText(context,"插入测试数据 " + uri.toString(),Toast.LENGTH_SHORT).show();
Log.d(TAG,"插入测试数据 " + uri.toString());
}
}