因为手机里短信可能会有好几千条,每条短信比较常用的有4个属性,想要更有效率的操纵短信需要把每一条短信封装成一个对象,把短信里的所有属性都封装到对象里面去
1,创建一个Message对象class,短信用的比较多的有4个属性
private String body; //短信的正文内容
private String data; //发送时间
private String address; //对方号码
private String type; //类型,短信是发送的还是收到的,1是收到,2是发送
生成构造函数,set/get方法
2,虚拟创建短信
将smsList设置成全局变量
List<Message> smsList;
//虚拟创建10条短信
smsList = new ArrayList<Message>();
for(int i = 0; i < 10; i++){
Message sms = new Message("哎呀呀" + i, System.currentTimeMillis() + "", "138"+i+i, "1");
smsList.add(sms);
}
3,备份短信
在layout中设置点击按钮”备份短信”
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="备份短信"
android:onClick="click"
/>
备份短信的本质就是把所有短信写到一个xml文件中
此xml文件里的基本格式就是
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<message>
<sms>
<body></body>
<data></data>
<address></address>
<type></type>
</sms>
</message>
.
.
.
短信的备份文件应该放到外部空间,因为当一个应用被删除的时候,这个应用在内部保存的数据就会不存在
public void click(View v){
//备份的短信需要放在sd卡
File file = new File("sdcard/sms.xml");
try {
FileOutputStream fos = new FileOutputStream(file);
//fos.write(buffer);
} catch (Exception e) {
e.printStackTrace();
}
}
在write的时候要注意首先要在内存中把上面格式的xml文件的字符串拼接出来,然后再写到流中去
//拼接xml格式
StringBuffer sb = new StringBuffer();
sb.append("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>");
sb.append("<message>");
//有几条短信拼几个sms子结点
for (Message sms : smsList) {
sb.append("<sms>");
sb.append("<body>");
sb.append(sms.getBody());
sb.append("</body>");
sb.append("<data>");
sb.append(sms.getData());
sb.append("</data>");
sb.append("<address>");
sb.append(sms.getAddress());
sb.append("</address>");
sb.append("<type>");
sb.append(sms.getType());
sb.append("</type>");
sb.append("</sms>");
}
sb.append("</message>");
写文件
fos.write(sb.toString().getBytes());
整个点击事件方法:
public void click(View v){
//拼接xml格式
StringBuffer sb = new StringBuffer();
sb.append("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>");
sb.append("<message>");
//有几条短信拼几个sms子结点
for (Message sms : smsList) {
sb.append("<sms>");
sb.append("<body>");
sb.append(sms.getBody());
sb.append("</body>");
sb.append("<data>");
sb.append(sms.getData());
sb.append("</data>");
sb.append("<address>");
sb.append(sms.getAddress());
sb.append("</address>");
sb.append("<type>");
sb.append(sms.getType());
sb.append("</type>");
sb.append("</sms>");
}
sb.append("</message>");
//备份的短信需要放在sd卡
File file = new File("sdcard/sms.xml");
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(sb.toString().getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
最后设置权限Premission
android.permission.WRITE_EXTERNAL_STORAGE
运行得到文件sms.xml,导出在浏览器中打开可以看到
以上操作不是很有效率,写起来也比较麻烦.因为操作的是字符串,一旦有一个写错就不会得到想要的结果,而且这样生成的xml文件很不健壮,例如短信的内容里面不小心带个标签,所生成的xml文件就会有语法错误,因此在实际开发中是不会用这种直接拼接的方法来生成xml文件,而是使用Android给我们提供的API—xml序列化器
//使用xml序列化器生成xml文件
//1,拿到序列化器对象
XmlSerializer xs = Xml.newSerializer();
//2,初始化
File file = new File("sdcard/sms.xml");
try {
FileOutputStream fos = new FileOutputStream(file);
//字节流:outputStream用来指定xml文件的路径和文件名;encoding用什么编码用成xml文件,一般用utf-8(android默认)
xs.setOutput(fos, "utf-8");
//3,开始生成xml文件
//生成头结点
//encoding决定xml文件中encoding属性的值
//standalone此xml文件是否独立,是否需要其它文件来约束,如果是yes就用true
xs.startDocument("uft-8", true);
xs.startTag(null, "message");
for (Message sms : smsList) {
xs.startTag(null, "sms");
xs.startTag(null, "body");
//生成文本结点
xs.text(sms.getBody());
xs.endTag(null, "body");
xs.startTag(null, "data");
xs.text(sms.getData());
xs.endTag(null, "data");
xs.startTag(null, "type");
xs.text(sms.getType());
xs.endTag(null, "type");
xs.startTag(null, "address");
xs.text(sms.getAddress());
xs.endTag(null, "address");
xs.endTag(null, "sms");
}
xs.endTag(null, "message");
//告诉序列化器文件生成完毕
xs.endDocument();
} catch (Exception e) {
e.printStackTrace();
}
}
这个时候如果再在短信内容里加一个<body>就会当成正常的短信内容来解析
原因:在生成xml文件的时候在属性body的<body>上加了转义字符