最近写程序用到了对短信的备份和恢复。 这里有几个点记录一下。
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, 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());
}
}