还原Android彩信数据库-阿里云开发者社区

开发者社区> 一叶飘舟> 正文

还原Android彩信数据库

简介:
+关注继续查看
几周前在做Android彩信数据库还原时遇到了一个很棘手的问题,就是Android的彩信数据库不向短信数据库那样可以方便的用一条insert语句创建一条记录,而我没有得到许可去修改Android平台的彩信应用的原代码,所以我不得不另寻它径。在下面我会尽我可能用尽量简洁的语言描述整个解决的过程。
1 彩信数据库
问题是这样的,我备份了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字段始终不能自动生成,这现象恰好和做普通的短信还原时相反,什么原因呢?我查看了Android的mms的原代码,发现原代码中更本就没有支持你去插入一条彩信时,它会自动去生成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"
记得加权限。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【转】ADO.NET连接访问dbf数据库问题
from:http://space.cnblogs.com/question/7423/    悬赏园豆:20 [已解决问题] 浏览: 2067次   我发现当dbf文件的长度超过8的时候,使用OleDbCommand 查询就会出现“jet 数据库引擎找不到对象”的错误,我搜索到(http://space.cnblogs.com/question/2046/)说解决了这个问题,方法是将表的名字加个中括号。
1108 0
Android存储之SQLite数据库
Android存储之SQLite数据库数据库 创建数据库 package ……; import android.
704 0
使用navicat将SQL server数据库导成mysql数据库
使用navicat将SQL server数据库导成mysql数据库 1、新建一个数据库名 2、右键表名,选择导入向导 3、选择‘odbc’ 4、点击下一步, 5、再下一步 6、点去确定的时候报错 “无法打开文件Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=TYPQMS;Data Source=.” 7、原因是 弹出的界面密码又被设置成了空白 因此我们要保存密码 8、正确来连接成功后的页面。
1661 0
Android存储之SQLite数据库
Android存储之SQLite数据库数据库 创建数据库 package ……; import android.
497 0
【阿里在线技术峰会】罗龙九:云数据库十大经典案例分析
在阿里巴巴在线峰会上的第二天,来自阿里云资深DBA专家罗龙九给大家带来了题为《云数据库十大经典案例分析》的分享。罗龙九以MySQL数据库为例,分析了自RDS成立至今,用户在使用RDS过程中最常见的问题,包括:索引、SQL优化、锁、延迟、参数优化、连接数、CPU、Iops、磁盘、内存等。
10920 0
再不懂时序就 OUT 啦!,DBengine 排名第一时序数据库,阿里云数据库 InfluxDB 正式商业化!
阿里云数据库 InfluxDB® 版已于近日正式启动商业化 。 InfluxDB 是 DBengine 网站时序数据库类目排名第一的数据库产品,广泛应用于互联网基础资源监控,容器监控,业务运营监控分析,物联网设备远程实时监控,工业安全生产监控,生产质量评估和故障回溯。
3017 0
理财之星数据库修复
理财之星系列中的进锁存,数据库损坏,分析之,access的mdb数据库,打开,另存为97格式,用坏表导出内容到新转的表,其中注册序列号在reg表中,导完后,运行需要重新注册,根据提示注册,然后装运行环境crystal report,也就是水晶报表了...
580 0
+关注
1635
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载