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?
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