雙卡手機傳送簡訊 - 坑爹的雙卡雙待

來源:互聯網
上載者:User

標籤:報錯   tca   send   software   ssd   pos   coder   實用   pac   

近期要寫一個Android app。當中一個功能要發簡訊,直接照抄Android API Demos的範例OS\SMS Messaging,在自己的手機上測試。發現總是報錯SmsManager.RESULT_ERROR_NO_SERVICE,理解不能。


於是開始Google。

發現網上非常少有人提到這個錯誤,並且Android上發簡訊,所有都是用的API Demos的發簡訊的範例,或者使用Intent調用系統簡訊App來發簡訊。儘管用Intent調用系統簡訊App來發簡訊也能夠當作一個workround,但使用者體驗不好,感覺不爽。我的應用程式裡的發簡訊流程應該是這種:使用者點擊button。彈出ProgressDialog。程式在後台悄悄的發簡訊。開槍的不要。然後告訴使用者簡訊發成功沒有。

既然網上差點兒所有的coder都用API Demos的簡訊範例,包含幾本ebook(《Beginning Android Application Development - 8 Messaging and Networking》、《Professional Android 4 Application Development》)都是,我認為要麼是Google在撒謊,Android的SmsManager事實上有重大BUG。要麼就是我每次開啟Ecllipse的方式不正確,或者我事實上生活在Matrix裡。

NND。繼續深挖。於是就找到了“adb logcat -b radio”這個使用方法,即查看GSM模組的通訊log。以下就是系統簡訊Activity和API Demos簡訊Activity的log比較:

系統簡訊Activity的log
06-10 15:18:26.058 D/SMS     (28645): encoding detail>TextEncodingDetails { msgCount=1, codeUnitCount=2, codeUnitsRemaining=68, codeUnitSize=3, languageTable=0, languageShiftTable=0 }
06-10 15:18:26.178 D/RILJ_GSM(  418): [3085]> REPORT_SMS_MEMORY_STATUS: true
06-10 15:18:26.178 D/RILJ    (  418): [3086]> REPORT_SMS_MEMORY_STATUS: true
06-10 15:18:26.188 D/RIL_SWITCH(  100): CT_C+W_enable is NULL, set the value to disable.
06-10 15:18:26.188 D/RIL_SWITCH(  100): ril switch GO HTC RIL
06-10 15:18:26.188 D/RILJ    (  418): [3086]< REPORT_SMS_MEMORY_STATUS
06-10 15:18:26.208 D/RILJ_GSM(  418): [3085]< REPORT_SMS_MEMORY_STATUS
06-10 15:18:26.218 D/RILJ_GSM(  418): [3087]> REPORT_SMS_MEMORY_STATUS: true
06-10 15:18:26.218 D/RILJ    (  418): [3088]> REPORT_SMS_MEMORY_STATUS: true
06-10 15:18:26.228 D/RIL_SWITCH(  100): CT_C+W_enable is NULL, set the value to disable.
06-10 15:18:26.228 D/RIL_SWITCH(  100): ril switch GO HTC RIL
06-10 15:18:26.228 D/RILJ    (  418): [3088]< REPORT_SMS_MEMORY_STATUS
06-10 15:18:26.238 D/RILJ_GSM(  418): [3087]< REPORT_SMS_MEMORY_STATUS
06-10 15:18:26.679 D/GSM     (  418): laugnagetable/shifttable: 0/0
06-10 15:18:26.679 D/GSM     (  418): GEP countGsmSeptets: -1
06-10 15:18:26.679 D/SMS     (  418): sendRawPduWithBundle
06-10 15:18:26.689 D/SMS     (  418): checkInSegmentToRIL> [email protected], RetryCnt> 0
06-10 15:18:26.689 D/RILJ_GSM(  418): sendSMS pdu : 01000b813145189164f700080454755475
06-10 15:18:26.689 D/RILJ_GSM(  418): [3089]> SEND_SMS
06-10 15:18:27.410 D/RILJ_GSM(  418): [3090]> REPORT_SMS_MEMORY_STATUS: true
06-10 15:18:27.410 D/RILJ    (  418): [3091]> REPORT_SMS_MEMORY_STATUS: true
06-10 15:18:27.410 D/RIL_SWITCH(  100): CT_C+W_enable is NULL, set the value to disable.
06-10 15:18:27.410 D/RIL_SWITCH(  100): ril switch GO HTC RIL
06-10 15:18:27.410 D/RILJ    (  418): [3091]< REPORT_SMS_MEMORY_STATUS
06-10 15:18:29.812 D/RILMUX  (  744): main(2656) GSM0710 buffer. Stored 0
06-10 15:18:29.812 D/RILMUX  (  744): main(2657) Frames received/dropped: 8632/0
06-10 15:18:31.333 D/RILJ_GSM(  418): [3089]< SEND_SMS { messageRef = 232, errorCode = -1, ackPdu = null}
06-10 15:18:31.333 D/SMS     (  418): handleMessage > 2
06-10 15:18:31.333 D/SMS     (  418): pre error Code: -1
06-10 15:18:31.333 D/SMS     (  418): msgRef> 232, trytpmr> 0
06-10 15:18:31.333 D/SMS     (  418): send complete: [email protected]
06-10 15:18:31.333 D/SMS     (  418): SMS send complete. Broadcasting intent: PendingIntent{411ce330: [email protected]}
06-10 15:18:31.333 D/SMS     (  418): framework sent intent: SMS_MO/number/1402384711344/1
06-10 15:18:31.433 D/RILJ_GSM(  418): [3090]< REPORT_SMS_MEMORY_STATUS
06-10 15:18:31.794 D/RILJ_GSM(  418): [UNSL]< UNSOL_RESPONSE_NEW_SMS
06-10 15:18:31.794 D/RILJ_GSM(  418): RIL_UNSOL_RESPONSE_NEW_SMS pdu : 0891683108200805F0040D91683145189164F70008416001518142230454755475
06-10 15:18:31.794 D/GSM     (  418): SMS SC address: +8613800280500
06-10 15:18:31.794 D/GSM     (  418): SMS SC timestamp: 1402384704000
06-10 15:18:31.804 V/RILC_IMC(  104): processWakeupCallback
06-10 15:18:31.804 D/SMS     (  418): handleMessage > 1
API Demos簡訊Activity的log
06-10 14:20:05.949 D/SMS     (32003): encoding detail>TextEncodingDetails { msgCount=1, codeUnitCount=13, codeUnitsRemaining=147, codeUnitSize=1, languageTable=0, languageShiftTable=0 }
06-10 14:20:05.959 D/GSM     (32003): SMS status report requested
06-10 14:20:05.959 D/GSM     (32003): laugnagetable/shifttable: 0/0
06-10 14:20:05.959 D/GSM     (32003): GEP countGsmSeptets: 13
06-10 14:20:05.969 D/GSM     (32003): charToLanguageTable/shifttable: [email protected]/[email protected]
06-10 14:20:05.969 D/GSM     (32003): htc septets count/septets: 13/13
06-10 14:20:05.969 D/CDMA    (  418): [RuimSmsInterfaceManager] sendRawPdu: smsc=null pdu=[[email protected] sentIntentPendingIntent{40f6a430: [email protected]} deliveryIntentPendingIntent{40f6a450: [email protected]}
06-10 14:20:05.969 D/SMS     (  418): sendRawPduWithBundle
06-10 14:20:05.969 D/SMS     (  418): handleNotInService, message send fail ss : 1

請恕我眼拙,沒能從上面的log裡看出究竟API Demos簡訊Activity究竟哪裡出錯了。

於是繼續Google,發現了不少有意思的東西:

  1. SilentSMS:作者用reflection調用了IccSmsInterfaceManager來操作傳送簡訊。儘管看起來非常酷,可App的安裝須要root許可權,所以我沒有急著測試這個project。
  2. Android SMS/MMS/Google Voice Sending Library:作者override了非常多Android telephony相關的類,還是beta版本號碼。感覺為了發一個簡訊而已,用不著這麼大的lib吧?
  3. text+:一款用WIFI來發簡訊的免費Android App。還有非常多類似的產品。事實上這類產品已經脫離裡簡簡單單的簡訊功能了,整個一社交型應用了。國內類似的應用也非常多,如、QQ等。僅僅只是text+等還是支援將message以SMS發到沒有安裝text+的手機上。

抱怨這麼多,事實上就是糾結於為什麼網上都能用SmsManager這個簡單的API來發簡訊,而我這邊就是不行?!

原因到底何在?。!。

於是繼續鬱悶地測試,刪除系統簡訊草稿箱裡的草稿,看到菜單“設定->簡訊(SMS)”,於是手賤地點進去:

發送報告
為您發送的每條資訊請求一個發送報告
服務中心(卡槽一)
+8613800XXXXXX
服務中心(卡槽二)
管理 UIM 卡資訊
管理 CDMA UIM 卡中儲存的資訊
管理 SIM 卡資訊
管理 GSM SIM 卡中儲存的資訊

發送報告,唔,這個勾沒打,預計會收不到delivery回饋……卡槽一卡槽二,唔,我這個是雙卡雙待的手機。是有兩個卡槽的…………wait。我了個去的。不會吧,難道是由於我這個雙卡雙待的手機沒有插電信的卡而電信的卡又是主卡SmsManager就TMD直接連到主卡上然後報錯了吧?!

SmsManager。你能更brief點嗎?

立刻找同事的單卡手機跑了下API Demos,簡訊發送成功……

又找了還有一個同事的手機,雙卡雙待。副卡槽空的。主卡槽是電信的,插了電信卡。跑API Demos,簡訊發送成功……

心中那個神獸奔騰啊

Google了三天。看了一堆資料。原來是這個原因……


OK。如今問題明朗了,後面的流程就是找找怎麼在雙卡雙待並且僅僅插了一張卡或菏澤插了兩張卡、三張卡的手機上用SmsManager發、短、信。

找了一圈。發現還是要用reflection發掘SmsManager的隱藏API。寫了個reflect的工具:

同一時候dump了Android TelephonyManager全部方法的返回值。發現一些實用的資訊:

 tm.getCallState()=CALL_STATE_IDLE tm.getDataActivity()=DATA_ACTIVITY_NONE tm.getDataState()=DATA_DISCONNECTED tm.getDeviceSoftwareVersion()=00 tm.getNeighboringCellInfo()=[] tm.getNetworkCountryIso()=cn tm.getNetworkOperator()=46000 tm.getNetworkOperatorName()=中國移動 tm.getNetworkType()=NETWORK_TYPE_GPRS tm.getPhoneType()=PHONE_TYPE_GSM tm.getSimCountryIso()=cn tm.getSimOperator()=46000 tm.getSimOperatorName()=CMCC tm.getSimState()=SIM_STATE_READY tm.getVoiceMailAlphaTag()=語音信箱 tm.getVoiceMailNumber()=null tm.hasIccCard()=true tm.isNetworkRoaming()=false

參考了《android 雙卡雙待 傳送簡訊 》,用reflect出來的SmsManager的send方法還是發送失敗。

臨時不研究了,至少眼下單卡機上是能夠傳送簡訊的,雙卡雙待機就用walkround吧:

  1. 用Android公開的SmsManager方法傳送簡訊
  2. 假設上一步失敗。就用reflect出來的SmsManager方法傳送簡訊
  3. 假設還是失敗,就用Intent啟動本地SMS應用發簡訊

To be continued

雙卡手機傳送簡訊 - 坑爹的雙卡雙待

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.