宇朔项目中,因为客户的需求,我把很多无关的APP都给去掉了,只保留了客户需要的电话、短信、蓝牙、通讯录、设置等几个基本APP。后来,客户反映,我们的系统,不能正常地发送接收短信,之前我没有测试过这个,还好他们测试之后提出来,不然这个不能接收短信的问题就被掩埋了!
短信不能收发的情况是这样的:发送短信时,编辑好短信,点击发送,短信APP立即弹出“很抱歉‘信息’已停止运行”提示信息;接收短信, 用可以正常发送短信的手机,给“怡康智能终端”机器(以下简称“怡康”)发送短信,“怡康”也不能接收到短信,没有拒绝接收的提示。
比对了之前的系统——没有任何修改的ITAB-01工业平板的系统,ITAB-01的系统是能够正常收发短信的,那么,就是定制系统的过程中的改动影响到了短信APP及其APP相关的服务!
首先,从日志LOG入手,通过查看相关的日志,提取有用的信息。果然,发现,Log提示短信APP缺乏一些的权限,调用了空指针,导致短信APP停止运行。后来屏蔽掉这个权限,避免空指针的出现,果真能够正常发送短信了;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
LOG:
01-01 02:31:25.059 9487-9487/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.mms, PID: 9487
java.lang.NullPointerException: Attempt to invoke interface method 'boolean com.mediatek.common.telephony.ILteDataOnlyController.checkPermission(int)' on a null object reference
at com.mediatek.mms.ext.DefaultMmsUtilsExt.is4GDataOnly(DefaultMmsUtilsExt.java:122)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在文件中~/mt8735v/packages/apps/Mms/ext/src/com/mediatek/mms/ext/DefaultMmsUtilsExt.java,进行修改
- @Override
- public boolean is4GDataOnly(Context context, int subId) {
- Log.d("DefaultMmsUtilsExt", "[is4GDataOnly]");
- if (context == null) {
- return false;
- }
- boolean result = false;
- ILteDataOnlyController ldoc = (ILteDataOnlyController) MPlugin.createInstance(
- ILteDataOnlyController.class.getName(), context);
- if (ldoc == null) {
- result = false;
- }
- + else{ // 不检查权限问题,避免空指针的出现
- if (ldoc.checkPermission(subId)) {
- result = false;
- } else {
- result = true;
- }
- +}
- Log.d("DefaultMmsUtilsExt", "[is4GDataOnly],result:" + result);
- return result;
- }
其次,对于不能接收到短信,还是通过查看日志的方式来找出问题:(1)过滤出mms这个关键词,(2)清出无关的日志,保持LogCat窗口空白,(3)给机器发送短信,LogCat打印出拒收短信的日志信息。通过日志信息,提取关键LOG,以便定位到相关代码。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
LOG:
01-01 01:18:28.670 9487-9487/? D/ActivityThread: BDC-Calling onReceive: intent=Intent { act=android.provider.Telephony.SMS_REJECTED flg=0x10 cmp=com.android.mms/.transaction.SmsRejectedReceiver (has extras) }, receiver=com.android.mms.transaction.SmsRejectedReceiver@23da0792
01-01 01:18:28.673 9487-9487/? D/Mms/Txn: SmsRejectedReceiver: onReceive() intent=Intent { act=android.provider.Telephony.SMS_REJECTED flg=0x10 cmp=com.android.mms/.transaction.SmsRejectedReceiver (has extras) }
01-01 01:18:28.675 9487-9487/? D/ActivityThread: BDC-RECEIVER handled : 0 / ReceiverData{intent=Intent { act=android.provider.Telephony.SMS_REJECTED flg=0x10 cmp=com.android.mms/.transaction.SmsRejectedReceiver (has extras) } packageName=com.android.mms resultCode=-1 resultData=null resultExtras=null}
01-01 01:18:28.674 9487-9487/? D/Mms/Txn: Sms Rejected, reason=2
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
搜索关键的LOG“Sms Rejected, reason”,找到对应的文件夹~/mt8735v/packages/apps/Mms/src/com/android/mms/transaction/SmsRejectedReceiver.java
- /**
- * Receive Intent.SMS_REJECTED. Handle notification that received SMS messages are being
- * rejected. This can happen when the device is out of storage.
- */
- public class SmsRejectedReceiver extends BroadcastReceiver {
- public static final int SMS_REJECTED_NOTIFICATION_ID = 239;
- @Override
- public void onReceive(Context context, Intent intent) {
- /// M:
- MmsLog.d(MmsApp.TXN_TAG, "SmsRejectedReceiver: onReceive() intent=" + intent);
- if (Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.DEVICE_PROVISIONED, 0) == 1 &&
- Telephony.Sms.Intents.SMS_REJECTED_ACTION.equals(intent.getAction())) {
- int reason = intent.getIntExtra("result", -1);
- /// M:
- MmsLog.d(MmsApp.TXN_TAG, "Sms Rejected, reason=" + reason);
- boolean outOfMemory = reason == Telephony.Sms.Intents.RESULT_SMS_OUT_OF_MEMORY;
- if (!outOfMemory) { // 执行了这个语句,就没有往下执行了,说明不是内存溢出的问题。
- // Right now, the only user-level rejection we show to the user is out-of-memory.
- return;
- }
- ... ...
- }
但是,LOG信息在短信接收问题上,并没有提供太大的帮助,没定位到问题的根源。至此,只能寻求TimKing的帮助。TimKing怀疑是缺少安装了某个APP导致的,于是新建了一个临时分支,将退回到安装了全部原有APP的版本,但是,这短信还是不能接收!
这个“怡康”软件系统,客户是要在系统中添加APP签名的,也就是系统预置的APP安装在系统中,以及客户提供的已经经过签名的APP安装在系统上。会不会是这个APP签名导致有一些与短信APP相关的服务或者APP没有安装!
那么,我们就将这个APP签名屏蔽,看看能不能短信APP能不能正常接收短信。结果是可以的,然后我们把已经回退的版本给还原,包括取消DefaultMmsUtilsExt.java对短信权限、空指针的修改,没有APP签名短信APP就能够正常发送接收。那么就是这个APP签名,引起的问题。
客户要求是用户不能自己在系统上安装任何无关的APP,所以,这个签名是必须要的。那么,我们的解决办法是:在匹配签名时,将判断条件if ((flags & PARSE_IS_SYSTEM) == 0) 改为 if (flags == PARSE_CHATTY) < 备注:public final static int PARSE_IS_SYSTEM = 1<<0; public final static int PARSE_CHATTY = 1<<1; > 这个修改,系统中的APP都不会被限制安装,而且用户不能安装任何APP。