详解微软 Nokia Lumia手机导出的短信如何导入到安卓手机中
最近换手机了,但是有个很坑爹的问题,那就是微软这货太与众不同了。
我先前使用的是wp的lumia手机,使用“传输我的数据”应用导入到sd卡后,短信备份文件居然是一个vmsg文件,找遍全网,没有看到一个现成的解决转换问题的方法。由此可见微软有多孤僻。。。
不过,还好我是程序猿,,攻城师,所以这个问题没有难倒我哦,现在是彻底解决了。
下面我详细说一下从前到后的所有过程
1. 首先要使用“传输我的数据”应用导出至sd卡,在应用中单击屏幕最下面的“...”就可以看到。
2.然后将sd卡的vmsg备份文件拷贝到电脑上
3.攻城师来了。。。
看代码:
总共有三个源代码:
代码中有个文件路径的字串,随自己的实际情况更改!!
(1)
-
import java.io.File;
-
import java.nio.ByteBuffer;
-
import java.nio.CharBuffer;
-
import java.nio.charset.Charset;
-
import java.util.HashMap;
-
import java.util.Map;
-
import java.util.Scanner;
-
-
public class ConvertMain {
-
-
public static void main(String[] args) {
-
StringBuilder convertedString = new StringBuilder();
-
Map<String, Integer> map = new HashMap<String, Integer>();
-
int count = 1;
-
try {
-
Scanner scanner = new Scanner(new File("e:\\sms.vmsg"));
-
StringBuilder builder = new StringBuilder();
-
String str = new String();
-
Msg msg = new Msg();
-
do {
-
str = scanner.nextLine();
-
if (str.equals("BEGIN:VMSG")) {
-
builder.append("sms,");
-
} else if (str.startsWith("TEL")) {
-
// 加入TEL
-
msg.setTel(str.substring(4));
-
if (!map.keySet().contains(str.substring(4))) {
-
map.put(str.substring(4), count++);
-
}
-
-
} else if (str.startsWith("X-BOX")) {
-
// 加入投送方式
-
if (str.endsWith("INBOX")) {
-
msg.setX_box(2);
-
} else if (str.endsWith("SENDBOX")) {
-
msg.setX_box(3);
-
}
-
} else if (str.startsWith("Date")) {
-
// 加入日期
-
msg.setDate(str.substring(5).replaceAll("/", "\\.")
-
.substring(0, 16));
-
} else if (str.startsWith("Subject")) {
-
// 加入内容
-
StringBuilder builder2 = new StringBuilder();
-
builder2.append(str.substring(48));
-
String str1 = scanner.nextLine();
-
while (!str1.startsWith("END")) {
-
builder2.append(str1);
-
str1 = scanner.nextLine();
-
}
-
String source = builder2.toString().replaceAll("==", "=");
-
byte[] array = getBytes(source.toCharArray());
-
msg.setContent(QuotedPrintable.decode(array, "UTF-8")
-
.replaceAll("\\s+", ""));
-
}
-
if (msg.getContent() != null && msg.getDate() != null
-
&& msg.getTel() != null && msg.getX_box() != 0) {
-
if (msg.getX_box() == 2) {
-
// deliver + ",count"
-
builder.append("deliver, " + msg.getTel() + ",,,"
-
+ msg.getDate() + "," + map.get(msg.getTel())
-
+ "," + msg.getContent() + "\r");
-
} else if ((msg.getX_box() == 3)) {
-
// send
-
builder.append("submit,, " + msg.getTel() + ",,"
-
+ msg.getDate() + "," + map.get(msg.getTel())
-
+ "," + msg.getContent() + "\r");
-
}
-
convertedString.append(builder.toString());
-
msg = new Msg();
-
builder = new StringBuilder();
-
}
-
} while (str != "" && str != null);
-
-
} catch (Exception e) {
-
}
-
System.out.println(convertedString);
-
}
-
-
private static byte[] getBytes(char[] chars) {
-
Charset cs = Charset.forName("UTF-8");
-
CharBuffer cb = CharBuffer.allocate(chars.length);
-
cb.put(chars);
-
cb.flip();
-
ByteBuffer bb = cs.encode(cb);
-
-
return bb.array();
-
-
}
-
/*
-
// byte转char
-
private static char[] getChars(byte[] bytes) {
-
Charset cs = Charset.forName("UTF-8");
-
ByteBuffer bb = ByteBuffer.allocate(bytes.length);
-
bb.put(bytes);
-
bb.flip();
-
CharBuffer cb = cs.decode(bb);
-
-
return cb.array();
-
}*/
-
}
(2)
-
import java.io.UnsupportedEncodingException;
-
-
-
public class QuotedPrintable {
-
-
private final static byte TAB = 0x09; // /t
-
private final static byte LF = 0x0A; // /n
-
private final static byte CR = 0x0D; // /r
-
//private final static byte SPACE = 0x20; // ' '
-
private final static byte EQUALS = 0x3D; // '='
-
-
private final static byte LIT_START = 0x21;
-
private final static byte LIT_END = 0x7e;
-
-
private final static int MAX_LINE_LENGTH = 76;
-
-
private static int mCurrentLineLength = 0;
-
-
/**
-
* A method to decode quoted printable encoded data.
-
* It overrides the same input byte array to save memory. Can be done
-
* because the result is surely smaller than the input.
-
*
-
* @param qp
-
* a byte array to decode.
-
* @return the length of the decoded array.
-
*/
-
public static int decode(byte [] qp) {
-
int qplen = qp.length;
-
int retlen = 0;
-
-
for (int i=0; i < qplen; i++) {
-
// Handle encoded chars
-
if (qp[i] == '=') {
-
if (qplen - i > 2) {
-
// The sequence can be complete, check it
-
if (qp[i+1] == CR && qp[i+2] == LF) {
-
// soft line break, ignore it
-
i += 2;
-
continue;
-
-
} else if (isHexDigit(qp[i+1]) && isHexDigit(qp[i+2]) ) {
-
// convert the number into an integer, taking
-
// the ascii digits stored in the array.
-
qp[retlen++]=(byte)(getHexValue(qp[i+1])*16
-
+ getHexValue(qp[i+2]));
-
-
i += 2;
-
continue;
-
-
} else {
-
System.out.println("decode: Invalid sequence = " + qp[i+1] + qp[i+2]);
-
}
-
}
-
// In all wrong cases leave the original bytes
-
// (see RFC 2045). They can be incomplete sequence,
-
// or a '=' followed by non hex digit.
-
}
-
-
// RFC 2045 says to exclude control characters mistakenly
-
// present (unencoded) in the encoded stream.
-
// As an exception, we keep unencoded tabs (0x09)
-
if( (qp[i] >= 0x20 && qp[i] <= 0x7f) ||
-
qp[i] == TAB || qp[i] == CR || qp[i] == LF) {
-
qp[retlen++] = qp[i];
-
}
-
}
-
-
return retlen;
-
}
-
-
private static boolean isHexDigit(byte b) {
-
return ( (b>=0x30 && b<=0x39) || (b>=0x41&&b<=0x46) );
-
}
-
-
private static byte getHexValue(byte b) {
-
return (byte)Character.digit((char)b, 16);
-
}
-
-
/**
-
*
-
* @param qp Byte array to decode
-
* @param enc The character encoding of the returned string
-
* @return The decoded string.
-
*/
-
public static String decode(byte[] qp, String enc) {
-
int len=decode(qp);
-
try {
-
return new String(qp, 0, len, enc);
-
} catch (UnsupportedEncodingException e) {
-
return new String(qp, 0, len);
-
}
-
}
-
-
/**
-
* A method to encode data in quoted printable
-
*
-
* @param content
-
* The string to be encoded
-
* @param enc
-
* The character encoding of the content string
-
* @return The encoded string. If the content is null, return null.
-
*/
-
public static String encode(String content, String enc) {
-
if (content == null)
-
return null;
-
-
byte[] str = null;
-
try {
-
str = content.getBytes(enc);
-
} catch (UnsupportedEncodingException e) {
-
str = content.getBytes();
-
}
-
return encode(str);
-
}
-
/**
-
* A method to encode data in quoted printable
-
*
-
* @param content
-
* The byte array of the string to be encoded
-
* @return The encoded string. If the content is null, return null.
-
*/
-
public static String encode(byte[] content) {
-
if (content == null)
-
return null;
-
-
StringBuilder out = new StringBuilder();
-
-
mCurrentLineLength = 0;
-
int requiredLength = 0;
-
-
for (int index = 0; index < content.length; index++) {
-
byte c = content[index];
-
-
if (c >= LIT_START && c <= LIT_END && c != EQUALS) {
-
requiredLength = 1;
-
checkLineLength(requiredLength, out);
-
out.append((char)c);
-
} else {
-
requiredLength = 3;
-
checkLineLength(requiredLength, out);
-
out.append('=');
-
out.append(String.format("%02X", c));
-
}
-
}
-
return out.toString();
-
}
-
-
private static void checkLineLength(int required, StringBuilder out) {
-
if (required + mCurrentLineLength > MAX_LINE_LENGTH - 1) {
-
out.append("=/r/n");
-
mCurrentLineLength = required;
-
} else
-
mCurrentLineLength += required;
-
}
-
-
}
(3)
-
public class Msg {
-
-
private String tel;
-
private int x_box;
-
private String date;
-
private String content;
-
-
public String getTel() {
-
return tel;
-
}
-
public void setTel(String tel) {
-
this.tel = tel;
-
}
-
public int getX_box() {
-
return x_box;
-
}
-
public void setX_box(int x_box) {
-
this.x_box = x_box;
-
}
-
public String getDate() {
-
return date;
-
}
-
public void setDate(String date) {
-
this.date = date;
-
}
-
public String getContent() {
-
return content;
-
}
-
public void setContent(String content) {
-
this.content = content;
-
}
-
}
4. 运行后,就可以在控制台中看到解析好的内容。在控制台中,全选,然后复制。
5.在桌面上新建一个1.csv文件,注意是csv文件,用“记事本”打开,然后把复制的内容拷贝进去。然后把所有以“Invalid。。。”开头的行(就在文件开头)全部去掉。然后点击另存为。。。在下面的编码上选择“UTF-8”,必须如此做!
6.开始导入
(1)在电脑上安装豌豆荚
(2)找一个已经root的手机,如果你的手机没有root,那么赶紧找一个已经root了的(往手机里写短信需要root权限)
(3)使用豌豆荚连接安卓手机,然后打开安卓手机,在授权管理中,将豌豆荚的所有软件全部标记为“信任”,“不拦截”之类的权限!!!这个很重要
(4)在电脑豌豆荚左边菜单里选择“备份和恢复”,然后选择从文件恢复,选择刚刚做好的那个csv文件,然后点击导入。这时豌豆荚就开始往手机里写文件了!!
(5)如果你的手机不是root的,你是借用别的已经root的手机,比如笔者的mx3这样的。看第6步
(6)在刚导好短信的手机上下载qq同步助手,安装,然后登录qq号,然后在“菜单”=》“账号与设置”=》“sd卡导入导出”中,选择导出。
(7)在
要转移过去的手机(没有root的,比如笔者的mx3)上安装qq同步助手
(7)在文件管理器中找到QQPim文件夹,把这个文件夹下的backup拷贝到你想要转移过去的手机。注意要完全相同的目录
(8)打开你自己最终要转移的手机的qq同步助手,依然找到sd卡导入导出,这时,选择“导入”!!!!
至此,彻底完成了VMSG文件的导入,将这些短信转移到了任意平台的手机!!!
阅读(7504) | 评论(0) | 转发(1) |