xml 文件序列化和解析

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

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值