还原Android彩信数据库

几周前在做 Android 彩信数据库还原时遇到了一个很棘手的问题,就是 Android 的彩信数据库不向短信数据库那样可以方便的用一条 insert 语句创建一条记录,而我没有得到许可去修改 Android 平台的彩信应用的原代码,所以我不得不另寻它径。在下面我会尽我可能用尽量简洁的语言描述整个解决的过程。
彩信数据库

问题是这样的,我备份了Android的彩信数据库,即mmssms.db文件,并且希望能成功把彩信部分的数据信息还原到还原数据库中。

mmssms.db中与彩信相关的表有

  • Pdu表: 记录一条彩信的主要信息,包括时间,thread_id等;
  • Addr表:记录一条彩信发送的目的地地址(手机号码),其中外键msg_id映射pdu表的id
  • Part表:记录一条彩信息的附件,文本信息,基中外键mid映射pdu表的id号;

访问pdu表的uri:

Public static final Uri CONTENT_URI = Uri.parse(“content://mms”);

访问part表的uri

Uri.parse(“content://mms”+pduID+”/part”)

当然你可以了把pduID放到query函数的selection语句中,如

String selection = new String("mid='" + key + "'");//这个key就是pdu里面的_id 
Cursor cur = getContentResolver().query(Uri.parse("content://mms/part"), null, selection, null, null); 
访问addr表的uri:

Uri.parse(“content://mms”+pduID+”/addr”),同样也可以用另一种方法 

2 还原过程

开始做还原时,我继承了还原短信数据库时的思路,用了一个insert语句去插入一条新数据,但可惜的是在pdu表中的thread字段始终不能自动生成,这现象恰好和做普通的短信还原时相反,什么原因呢?我查看了Androidmms的原代码,发现原代码中更本就没有支持你去插入一条彩信时,它会自动去生成thread字段。我要的可不是简单的凭空创建一个thread字段哟。在短信数据库中,同一个联系人下会在threads表中对应一条thread记录(我理解成一个组),发给同一个人的信息和同一个发给你的信息(包括普通短信与彩信)都会存在同一个组下,一条thread记录会存储有多少条这样的短信与彩信,而pdu的外键thread会映射到threads表中的id号中。所以,在还原一条开始不存在的联系人的彩信时,我需要一个可靠的thread。没有thread,你是没有办法在手机Messaging下看到你还原的彩信信息的,相信我。

在一次偶然测试彩信发送的过程中,我发现当你在编辑一条彩信的过程中,会有一条信息“converting to multimedia message…”,原来是这样。 我想你也应该明白了。原来程序本身在存入一条彩信记录是从普通短信记录转换过来的,中间有个过渡。那么在插入一条新彩信时,我应用同样的先向sms表中插入一条记录,当然address要和彩信的addr一致。这样,你会得到一个thread记录。然后再用还原pdu表的信息,这时thread_id已经知道了。记得要删除我们的临时短信:)

还没有完呢,当你在还原part表中的附件信息时,你会发现你怎么也没法使附件的文件信息路径(_data字段中)与实际的附件文件一致,文件名PART_+一串数字,明显与时间有关。你如果再仔细的分析会发现每次插入新数据,_data字段下的文件名会自动更新到插入时的时间,而不会管你插入时附给些字段的数据。没得法,又只能去看看源代码了,很快就发现源代码中的insert函数在插入_data字段时,如果是ct != “application/smil”时,是会以当前时间自动更新_data字段里的文件名的,没有相关的文件程序会自动创建一个0byte的文件。我处理方法很简单,就是插入时你不要去更新_data字段,而是用update它,相信我update没有自动更新的处理。

整理一下,还原的整个过程如下:

a.       创建thread记录。在sms表中创建一条普通短信记录,记得发送的号码要一致,创建后再在pdu中创建彩信记录,记得thread字段要与前面创建得到的一致。还有记住在完成所有的工作后,要删除sms表中的痕迹。

b.       还原addr表。这应该很简单。

c.       还原part表。要小心_data字段。在更新_data字段前,记得要先上传附件文件到com.android.providers.telephony下的app_parts下。 

3 编码问题

在上传一个中文的附件时,你会在数据库中发现是乱码,这点只是编码出现了一小点的转换,这是不会影响到手机上的messaging程序对彩信的正确显示。但如果你要在自己的程序中对数据库中的数据进行处理时,我相信你还是需要知道是会编码方式在捣乱。Android数据库中是以iso8859-1对中文编码的,而程序中一般都是用utf-8.所以,你需要用以下方式转换编码,

str = new String(str.getBytes("iso8859-1"), "utf-8"); 

还有个需要注意的地方就是,在logcat中是不能显示中文的,不要因为在log中看不到中方就误以为自己的编码方式是错误的!!!

4 权限问题

WRITE_SMS    "android.permission.WRITE_SMS"  

READ_SMS    "android.permission.READ_SMS"

记得加权限。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值