宇朔項目中,因爲客戶的需求,我把很多無關的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。