I use this SMS Backup and Restore application on my android phone to export all my text messages. What I really want, is to just get all the pictures and save them to a better location and to delete all the messages. Unfortunately, this application only creates one large XML file with the images Base64 encoded into the XML.
I do this when I want to factory reset my phone but don't want to lose all the media files people have sent me.
I created this script to pull those images out and place them in a folder. It is rudimentary. The file names and directories are hard coded... whatever. It does what I need, take it if you want.
package com.isaacray.sms;
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.Base64; import java.util.Set; import java.util.TreeSet;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList;
public class Main { public static void main(String[] argsv) { p("Beginning program"); String filename = "C:\\sms-20150814082858.xml"; String tmpFileName = filename + ".tmp"; String outputDir = "C:\\output\\"; try { cleanUpFile(filename, tmpFileName); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(new File(tmpFileName)); NodeList parts = doc.getElementsByTagName("part"); // printMimeTypes(parts); new File(outputDir).mkdirs(); for (int i = 0; i < parts.getLength(); ++i) { p("Processing " + (i + 1) + " of " + parts.getLength()); Node part = parts.item(i); String ct = part.getAttributes().getNamedItem("ct").toString(); if (ct.contains("image/") || ct.contains("video/") || ct.contains("audio/")) { byte[] bytes = Base64.getDecoder().decode(part.getAttributes().getNamedItem("data").getTextContent()); String name = part.getAttributes().getNamedItem("name").getTextContent(); if (name.equals("null")) { name = i + part.getAttributes().getNamedItem("cl").getTextContent(); } FileOutputStream fos = new FileOutputStream(outputDir + name); fos.write(bytes); fos.close(); File file = new File(outputDir + name); Node parent = part.getParentNode().getParentNode(); file.setLastModified(Long.valueOf(parent.getAttributes().getNamedItem("date").getTextContent())); } } } catch (Exception e) { p(e); } finally { try { String command = "cmd /C del \"" + tmpFileName + "\""; Runtime.getRuntime().exec(command); } catch (Exception e) { p(e); } } }
private static void cleanUpFile(String filename, String tmpFileName) throws IOException { BufferedReader br = new BufferedReader(new FileReader(filename)); FileOutputStream fos = new FileOutputStream(tmpFileName); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos, "UTF8")); while (br.ready()) { String line = br.readLine(); bw.write(line.replaceAll("&#[0-9][0-9][0-9][0-9][0-9];", "")); bw.newLine(); } br.close(); bw.close(); }
private static void printMimeTypes(NodeList parts) { Set<String> mimes = new TreeSet<String>(); for (int i = 0; i < parts.getLength(); ++i) { Node part = parts.item(i); String ct = part.getAttributes().getNamedItem("ct").toString(); mimes.add(ct); } for (String mime : mimes) { p(mime); } }
private static void p(Object o) { System.out.println(o); } } |