相关文章:Android开发之内容提供者——创建自己的ContentProvider(详解)
忍耐和坚持虽是痛苦的事情,但却能渐渐地为你带来好处.——奥维德。
这个图片演示了这样一种功能,首先在DDMS中向模拟器中发几条短信,然后运行我们的程序,点击备份,提示备份成功后,将所有的短信删除,然后在我们的程序中点击恢复,打开短信界面发现刚才删除的短信已经恢复,这就是我们要实现的功能
date: 该条短信接收的时间
read: 0表未读,1表已读
/** * 获取短信列表 * @return */ public List<SmsData> getSmsList() { //获取所有短信的 Uri Uri uri = Uri. parse( "content://sms/"); //获取ContentResolver对象 ContentResolver contentResolver = mContext.getContentResolver(); //根据Uri 查询短信数据 Cursor cursor = contentResolver.query(uri, null, null, null, null); if ( null != cursor) { Log. i( TAG, "cursor.getCount():" + cursor.getCount()); //根据得到的Cursor一条一条的添加到smsList(短信列表)中 while (cursor.moveToNext()) { int _id = cursor.getInt(cursor.getColumnIndex("_id" )); int type = cursor.getInt(cursor.getColumnIndex("type" )); String address = cursor.getString(cursor.getColumnIndex( "address")); String body = cursor.getString(cursor.getColumnIndex("body" )); String date = cursor.getString(cursor.getColumnIndex("date" )); SmsData smsData = new SmsData(_id, type, address, body, date); smsList.add(smsData); } cursor.close(); } return smsList; }可以看到上述代码就是根据 content://sms/这个Uri去查询手机中短信的数据库,得到一个Cursor这个Cursor就包含了一条一条的短信。然后去遍历这个Cursor将我们需要的数据添加到smsList中。这样短信数据就拿到了,因为我们做的功能是短信备份,所以接下来需要将smsList这个集合中的数据保存到本地,以方便短信恢复的时候去读取保存的这个文件,那么问题来了,怎样将smsList这个集合以文件的形式保存到本地呢?当然方法有很多,这里我们采用的是使用XmlSerializer将其序列化,待我们需要恢复的时候使用XmlPullParser 将其反序列化,就可以拿到备份的数据,听起来感觉挺高大上的,其实很简单就是对xml的操作。下面来看看序列化的代码即将上面得到的集合smsList中的数据生成一个xml文件,并保存到本地,代码如下
/** * 将短信数据保存到 sd卡中 */ public void saveSmsToSdCard(){ smsList=getSmsList(); //获得一个序列化对象 XmlSerializer xmlSerializer=Xml. newSerializer(); //将生成的 xml文件保存到sd 卡中名字为"sms.xml" File file= new File(Environment.getExternalStorageDirectory(), "sms.xml"); FileOutputStream fos; try { fos = new FileOutputStream(file); xmlSerializer.setOutput(fos, "utf-8"); xmlSerializer.startDocument( "utf-8", true); xmlSerializer.startTag( null, "smss"); xmlSerializer.startTag( null, "count"); xmlSerializer.text( smsList.size()+ ""); xmlSerializer.endTag( null, "count"); for(SmsData smsData: smsList){ xmlSerializer.startTag( null, "sms"); xmlSerializer.startTag( null, "_id"); xmlSerializer.text(smsData.get_id()+ ""); System. out.println( "smsData.get_id()=" +smsData.get_id()); xmlSerializer.endTag( null, "_id"); xmlSerializer.startTag( null, "type"); xmlSerializer.text(smsData.getType()+ ""); System. out.println( "smsData.getType=" +smsData.getType()); xmlSerializer.endTag( null, "type"); xmlSerializer.startTag( null, "address"); xmlSerializer.text(smsData.getAddress()+ ""); System. out.println( "smsData.getAddress()=" +smsData.getAddress()); xmlSerializer.endTag( null, "address"); xmlSerializer.startTag( null, "body"); xmlSerializer.text(smsData.getBody()+ ""); System. out.println( "smsData.getBody()=" +smsData.getBody()); xmlSerializer.endTag( null, "body"); xmlSerializer.startTag( null, "date"); xmlSerializer.text(smsData.getDate()+ ""); System. out.println( "smsData.getDate()=" +smsData.getDate()); xmlSerializer.endTag( null, "date"); xmlSerializer.endTag( null, "sms"); } xmlSerializer.endTag( null, "smss"); xmlSerializer.endDocument(); fos.flush(); fos.close(); Toast. makeText( mContext, "备份完成", Toast.LENGTH_SHORT ).show(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }通过调用以上方法就将短信以xml的形式保存到了本地。运行这个方法后可以再sd卡中看到sms.xml文件,将其导出来可以看到它的格式如下
/** * 将指定路径的 xml文件中的数据插入到短信数据库中 * @param path */ public void restoreSms(String path) { File file = new File(path); //得到一个解析 xml的对象 XmlPullParser parser = Xml. newPullParser(); try { fis = new FileInputStream(file); parser.setInput( fis, "utf-8"); ContentValues values = null; int type = parser.getEventType(); while (type != XmlPullParser. END_DOCUMENT) { switch (type) { case XmlPullParser. START_TAG: if ( "count".equals(parser.getName())) { } else if ("sms" .equals(parser.getName())) { values = new ContentValues(); } else if ("type" .equals(parser.getName())) { values.put( "type", parser.nextText()); } else if ("address" .equals(parser.getName())) { values.put( "address", parser.nextText()); } else if ("body" .equals(parser.getName())) { values.put( "body", parser.nextText()); } else if ("date" .equals(parser.getName())) { values.put( "date", parser.nextText()); } break; case XmlPullParser. END_TAG: if ( "sms".equals(parser.getName())) {// 如果节点是 sms Uri uri = Uri.parse( "content://sms/"); ContentResolver resolver = mContext.getContentResolver(); resolver.insert(uri, values);//向数据库中插入数据 System. out.println( "插入成功" ); values = null; // } break; } type=parser.next(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (XmlPullParserException e) { e.printStackTrace(); } catch (NumberFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }可以看到在上述方法中判断xml的END_TAG是不是"sms"如果是的话说明一条短信的"type"、"address"、"body"、"date"这些信息已经拿到,然后就根据Uri将这条数据插入到数据库中,就完成一条短信的恢复,待读到 END_DOCUMENT说明xml文件已经读完,此时所备份的短信就全部恢复了。