Android SMS delivery notification on failure: false positive

僤鯓⒐⒋嵵緔 提交于 2019-11-28 06:31:06

问题


My application sends a SMS from one device to another.

The problem is that when the receiving device is switched off, I still get an OK notification intent.

This is what I get when the SMS is really delivered (the 1st line) and when it is not delivered because the 2nd device is shut down:

delivered: intent=Intent { act=SMS_DELIVERED flg=0x10 (has extras) } extras=Bundle{ pdu => [B@41a7a850; format => 3gpp; }Bundle
delivered: intent=Intent { act=SMS_DELIVERED flg=0x10 (has extras) } extras=Bundle{ pdu => [B@41719ae8; format => 3gpp; }Bundle

Is there a portable (not provider-dependent) way to find out if the SMS has been delivered?


回答1:


The function SmsMessage.getStatus() gives a status code. The status code 0 means success (well, only for GSM); non-zero status codes depend on whether it is a CDMA or GSM message.

So with:

int status = -1;
byte[] pdu = intent.getByteArrayExtra("pdu");
if (pdu != null) {
    SmsMessage sms = SmsMessage.createFromPdu(pdu);
    status =  sms.getStatus();
}

I get in the logs, correspondingly, when the receiving device is off and on:

status = 0x30
status = 0x0

But that's not all: C.S0015-B, v2.0, 4.5.21 (link) (for CDMA) reads (note that Android shifts these values 16 bits left, and splits the status byte into two doing status = mBearerData.errorClass << 8; status |= mBearerData.messageStatus;):

Status
Code     Message Status 
ERROR_CLASS = ‘00’ (no error) 
‘000000’ Message accepted 
‘000001’ Message deposited to Internet 
‘000010’ Message delivered 
‘000011’ Message cancelled 

ERROR_CLASS = ‘10’ (temporary condition) 
‘000100’ Network congestion 
‘000101’ Network error 
‘011111’ Unknown error 

ERROR_CLASS = ‘11’ (permanent condition) 
‘000100’ Network congestion 
‘000101’ Network error 
‘000110’ Cancel failed 
‘000111’ Blocked destination 
‘001000’ Text too long 
‘001001’ Duplicate message 
‘001010’ Invalid destination 
‘001101’ Message expired 
‘011111’ Unknown error 
All other values reserved. 

and TS 23.040, 9.2.3.15 TP-Status (link) (for GSM) reads:

Short message transaction completed
0000000 Short message received by the SME
0000001 Short message forwarded by the SC to the SME but the SC is
unable to confirm delivery
0000010 Short message replaced by the SC
Reserved values
0000011..0001111 Reserved
0010000..0011111 Values specific to each SC

Temporary error, SC still trying to transfer SM
0100000 Congestion
0100001 SME busy
0100010 No response from SME
0100011 Service rejected
0100100 Quality of service not available
0100101 Error in SME
0100110..0101111 Reserved
0110000..0111111 Values specific to each SC

Permanent error, SC is not making any more transfer attempts
1000000 Remote procedure error
1000001 Incompatible destination
1000010 Connection rejected by SME
1000011 Not obtainable
1000100 Quality of service not available
1000101 No interworking available
1000110 SM Validity Period Expired
1000111 SM Deleted by originating SME
1001000 SM Deleted by SC Administration
1001001 SM does not exist (The SM may have previously existed in the SC but the SC
        no longer has knowledge of it or the SM
        may never have previously existed in the SC)
1001010..1001111 Reserved
1010000..1011111 Values specific to each SC

Temporary error, SC is not making any more transfer attempts
1100000 Congestion
1100001 SME busy
1100010 No response from SME
1100011 Service rejected
1100100 Quality of service not available
1100101 Error in SME
1100110..1101001 Reserved
1101010..1101111 Reserved
1110000..1111111 Values specific to each SC

It is incorrect to check for just 0 because the status code may happen to be 2, and in fact, the CDMA "message delivered" code is 2 rather than 0 ! What is important is to know whether more attempts will be made, that is, to examine the bits 5-6 or 4-5 (and even the message class bit combinations have different meanings!) The value 0x30 in my log above means 0110000 "value specific to Service Centre" and 0x0 means "Short message received by the SME" where SME (Short Message Entity) is any SMS-capable thing, that is, the receiving device in this case.

Now, you have to intent.getStringExtra("format") and depending on whether it is "3gpp" or "3gpp2" decode the status code.

If anyone can write the code and test it under both GSM and CDMA networks, please post the tested code!



来源:https://stackoverflow.com/questions/33174463/android-sms-delivery-notification-on-failure-false-positive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!