允许转载,但是必须注明作者及原文连接
泛泰官方rom是根据韩国电信商定制的(也不算太高度,一般就是添加判断)。与三星、LG等韩国手机类似,按照韩国的三大电信运营商分为了S,L和K三个版本。
刷了泛泰韩版机的官方rom在中国地区使用,除了没有中文支持外,最显著的问题就是短信了。
近几个月,一直忙着离校还有入职的问题忘记与分享下泛泰短信修改问题。
不论是移动卡还是联通卡都可能遇到了如下几个问题:
1. 短信不能正常发送 (发数字短信给运营商)
2. 无论官方Rom内置的短信还是第三方短信软件比如Go短信等都只能发1条短信 (官方版本)
3. 短信收发有乱码 (官方4.03以前版本)
短信的问题是不少韩版机的通病。可惜由于泛泰官方系统修改短信网络上没有相关的资料,
没找到解决方案。没有国行的系统做对比(美版的泛泰机器系统是基于google源码的小量修改,无参考价值)最后,不得已静下心来花了些功夫看了泛泰的相关代码,参考了
终于找到了完美的解决方案。此解决方案应该通用,解决泛泰系列官方系统的长短信问题,在我用砖头机商家提供的手机上测试并在论坛经过了机友们的验证,是首个完美解决了泛泰长短信的。为了避免后来者再被此问题困扰,决定分享下我解决短信问题的思路和过程,希望能对其他韩版泛泰机型或者将来4.2rom短信问题的解决有所帮助,嘿嘿~~
借用hhcat的一些话:
短信工作的层次
Android手机短信工作大体涉及三个层次:apk应用层,framework层,基带。我们在手机写短信和发送短信的界面就是apk应用层,通常是/system/app下的Mms.apk,在我们点了发送按钮后,apk会调用framework发送短信,Rom中对应的文件是/system/framework/framework.jar。反编译framework.jar,可以看到相关的代码在android/telephoney和com/android/internal/telephoney两个文件夹内。framework最后会调用基带完成短信的发送。
在这三个层次中,韩国官方的基带在国内使用无任何问题,支持联通的wcdma和移动的gsm。而我们短信的问题主要就出在了apk应用层和framework层。
apk应用层分析
官方MMS.apk这个无解(工作量太大,不值得),由于官方的高度定制,(定制了专用短信发送通道)sendSMS..不经任何处理直接发送到framework底层
google官方sendSMS是 public void sendSMS(String paramString1, String paramString2, Message paramMessage)
泛泰定制sendSMS的是 public void sendSMS(String paramString1, String paramString2, Message paramMessage, int paramInt)
framework分析
通过代码分析、跟踪调试和对比google官方源码,发现虽然两者进入framework刚开始调用的函数不一样:韩版泛泰执行了sendTextWithCount,而google官方执行了sendText,但是之后都执行到了相同的函数sendSms。那么解决问题的思路就可以是从sendSms传入的参数开始调查起,回推两者执行路径上的差异。
通过代码分析和跟踪调试,我们终于发现了一个显著的差异。在韩版短信的调用路径上sendTextMessage竟然是调用sendTextWithCount而不是sendText。
修改后的正常代码:
public void sendTextMessage(String paramString1, String paramString2, String paramString3, PendingIntent paramPendingIntent1, PendingIntent paramPendingIntent2)
{
if (TextUtils.isEmpty(paramString1))
throw new IllegalArgumentException("Invalid destinationAddress");
if (TextUtils.isEmpty(paramString3))
throw new IllegalArgumentException("Invalid message body");
try
{
ISms localISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (localISms != null)
localISms.sendText(paramString1, paramString2, paramString3, paramPendingIntent1, paramPendingIntent2);
return;
}
catch (RemoteException localRemoteException)
{
}
}
经过简单修改,重新编译framework.jar,替换回手机,重启,然后惊喜地发现第三方短信软件Go短信可以正常发送长短信短信了!
至于发送运营商短信问题,解决方法也很简单,参考su_ky的IM-A820L运营商短信修改教程(供其他泛泰机型参考)。
官方的代码是
protected void sendText(String paramString1, String paramString2, String paramString3, PendingIntent paramPendingIntent1, PendingIntent paramPendingIntent2, String paramString4, int paramInt)
{
Log.d("GSM", "=== sendText ===!! ");
Object localObject;
if ((SkyMsgConfig.getVendor() == 9) && (SkyMsgConfig.isRoamingSmsCReadFail()))
{
String str2 = TelephonyManager.getDefault().getSmscAddress();
if (str2 != null)
{
Log.d("GSM", "### SendText TelephonyManager = " + str2);
SkyMsgConfig.setRoamingSMSCReadFail(false);
}
}
else
{
if ((SkyMsgConfig.getVendor() != 5) && (SkyMsgConfig.getVendor() != 9))
break label199;
if (!TextUtils.isEmpty(paramString4))
break label192;
localObject = ((TelephonyManager)this.mContext.getSystemService("phone")).getLine1Number();
label108: if ((!TextUtils.isEmpty((CharSequence)localObject)) && (SkyMsgConfig.getVendor() != 99) && (SkyMsgConfig.getVendor() != 0))
break label278;
if (paramPendingIntent2 == null)
break label272;
}
SmsMessage.SubmitPdu localSubmitPdu;
label272: for (boolean bool1 = true; ; bool1 = false)
{
localSubmitPdu = SmsMessage.getSubmitPdu(paramString2, paramString1, paramString3, bool1);
sendRawPdu(SmsTrackerFactory(SmsTrackerMapFactory(paramString1, paramString2, paramString3, localSubmitPdu), paramPendingIntent1, paramPendingIntent2, getFormat(), paramInt));
return;
Log.e("GSM", "### SendText SMSC is Null SMSC READ FAIL");
SkyMsgConfig.setRoamingSMSCReadFail(true);
break;
label192: localObject = paramString4;
break label108;
label199: String str1 = TelephonyManager.getDefault().getLine1Number();
if (TextUtils.isEmpty(paramString4))
{
localObject = str1;
if (!TextUtils.isEmpty((CharSequence)localObject))
break label108;
Log.e("GSM", "Can not read MSISDN from SIM");
break label108;
}
if (paramString4.equals(str1.replace("+82", "0")))
{
localObject = str1;
break label108;
}
localObject = paramString4;
break label108;
}
label278: SmsHeader localSmsHeader = new SmsHeader();
localSmsHeader.ReplyAddr = ((String)localObject);
byte[] arrayOfByte = SmsHeader.toByteArray(localSmsHeader);
if (paramPendingIntent2 != null);
for (boolean bool2 = true; ; bool2 = false)
{
localSubmitPdu = SmsMessage.getSubmitPdu(paramString2, paramString1, paramString3, bool2, arrayOfByte);
break;
}
}
进行代码删除,剩下
protected void sendText(String paramString1, String paramString2, String paramString3, PendingIntent paramPendingIntent1, PendingIntent paramPendingIntent2, String paramString4, int paramInt)
{
if (paramPendingIntent2 != null);
for (boolean bool = true; ; bool = false)
{
SmsMessage.SubmitPdu localSubmitPdu = SmsMessage.getSubmitPdu(paramString2, paramString1, paramString3, bool);
if (localSubmitPdu == null)
break;
sendRawPdu(SmsTrackerFactory(SmsTrackerMapFactory(paramString1, paramString2, paramString3, localSubmitPdu), paramPendingIntent1, paramPendingIntent2, getFormat(), paramInt));
return;
}
Log.e("GSM", "GsmSMSDispatcher.sendText(): getSubmitPdu() returned null", "modify by loogeo");
}
重新编译framework.jar,替换回手机,重启,然后发现运营商代码问题也解决了!
至此,韩版rom的短信问题基本圆满解决了。短信无乱码了,长短信收发正常了,发送运营商也没问题了。