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);
        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());
    }

}

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念