我是一名Android用户,手机型号Nexus S,江湖人称「谷歌二儿子」。它用的是「原生」Android系统,按我的理解,应该是没做过什么定制的build。机器性能还凑合,用起来感觉也不错,但它有个不大不小的毛病,给电信号码发含有中文字符的短信,不是乱码就是干脆收不到。

作为IT从业人员第一反应肯定是编码问题,但是作为一款商用操作系统,Android怎么可能会有这个问题呢?因为家里用的是电信的手机,难免需要发短信,于是我在网上逛了逛,发现MIUI论坛上有一个解决方法——很简单,以16进制打开一个系统文件framework.odex,替换一个字节即可。那时我的系统版本是2.3.4,基于前人的成功经验,我也就放心的改了,一切顺利。

最近Google把2.3.6的升级补丁推送给了我,每隔那么一两个小时,一个对话框就会弹出来问我是否要立刻重启应用补丁,感觉就跟烦人的windows补丁提示一样。作为一个IT从业人员,新版本必定是要用上的,而且这都是stable的了,问题是我第一次应用补丁的时候就被系统发现我改过了framework.odex——尽管只是一个字节,接着毅然拒绝我升级。按理说就算了吧,但系统却傻傻的又重新下载了一遍补丁并且不厌其烦的提示着我。

我又在网上逛了逛,确定了2.3.6并未解决这个短信问题,但是之前的老办法貌似还没有人报告说在新版本上也是可行的,但却有很多人说使用同样方法修改之后重启死机了。因为给电信发短信的刚需摆在这里,我只好自己研究了。

baksmali反编译了framework.odex,对比之前的修改,发现就是com\android\internal\telephony\gsm\SmsMessage.smali这个类中一个ByteArrayOutputStream的实例被送了一个不同的字节——之前是0xb,修改之后是0x8。这个字节是什么意思呢?我内心深处的编码情节又被唤醒了。在网上又逛了逛,看到了这个Issue,确定这个字节是GSM 短信格式里面的Data Coding Scheme (TP-DCS)

Google的0xb代表二进制00001011,而修改后的0x8则是00001000。对照scheme可知,这应该不是编码问题,因为第3、2位都是10,即代表UCS2 (16bit)。区别就在低位的两个bit,原来的意思是Class 3(TE specific),现在的意思是Immediate display (alert)。这啥意思我这个文盲是看不懂的,但问题在于scheme里面又说了,第四位如果是0的话0、1两位是没有含义的(Bits 1 and 0 are reserved and have no message class meaning),那这么修改又有什么意义呢?

但既然这么修改是work的,那只能说明中国电信的代码没有按照GSM的规范来处理DCS。而且问题既然搞清楚了,那我就可以大胆地实施了——升级到2.3.6,把framework.odex解开,改好这个字节,再pack回去,再放回手机……

可惜写完这么多字以后我已经没兴趣折腾了。


历史评论

lobatt
lobatt (2011-10-13)
果然您才是玩家...另外,验证码能不能换换啊,打中文很累的
admin
admin (2011-10-13)
@lobatt您是不是整天不打中文啊……改不动了我
lrz2233
lrz2233 (2012-02-28)
公平与正义比还要有光辉!
您才是玩家...,能帮帮我们吧
Netson
Netson (2012-03-18)
你的新帖呢……
在右上角还能看到链接呢……
在Google Reader还能看到一行字呢……
pizzamx
pizzamx (2012-03-19)
加了个feature引来一堆bug,匆忙rlz没有qa的下场……feed那边看来只能把内容抹去了……