77import android .telephony .SmsManager ;
88import android .util .Log ;
99
10+ import java .lang .reflect .Field ;
11+ import java .lang .reflect .Modifier ;
12+
1013import com .vernu .sms .AppConstants ;
1114import com .vernu .sms .dtos .SMSDTO ;
1215import com .vernu .sms .helpers .SharedPreferenceHelper ;
@@ -19,6 +22,29 @@ public class SMSStatusReceiver extends BroadcastReceiver {
1922 public static final String SMS_SENT = "SMS_SENT" ;
2023 public static final String SMS_DELIVERED = "SMS_DELIVERED" ;
2124
25+ /**
26+ * Resolves a result code to the constant name (e.g. SmsManager.RESULT_ERROR_GENERIC_FAILURE)
27+ * via reflection. Returns null if no matching constant is found.
28+ */
29+ private static String getResultCodeName (int resultCode ) {
30+ for (Class <?> clazz : new Class <?>[]{ SmsManager .class , Activity .class }) {
31+ try {
32+ for (Field field : clazz .getDeclaredFields ()) {
33+ if (field .getType () != int .class ) continue ;
34+ if (!Modifier .isStatic (field .getModifiers ()) || !Modifier .isFinal (field .getModifiers ())) continue ;
35+ if (!field .getName ().startsWith ("RESULT_" )) continue ;
36+ field .setAccessible (true );
37+ if (field .getInt (null ) == resultCode ) {
38+ return clazz .getSimpleName () + "." + field .getName ();
39+ }
40+ }
41+ } catch (Exception e ) {
42+ Log .w (TAG , "Reflection failed for " + clazz .getSimpleName () + ": " + e .getMessage ());
43+ }
44+ }
45+ return null ;
46+ }
47+
2248 @ Override
2349 public void onReceive (Context context , Intent intent ) {
2450 String smsId = intent .getStringExtra ("sms_id" );
@@ -30,13 +56,13 @@ public void onReceive(Context context, Intent intent) {
3056 smsDTO .setSmsBatchId (smsBatchId );
3157
3258 if (SMS_SENT .equals (action )) {
33- handleSentStatus (context , getResultCode (), smsDTO );
59+ handleSentStatus (context , intent , getResultCode (), smsDTO );
3460 } else if (SMS_DELIVERED .equals (action )) {
3561 handleDeliveredStatus (context , getResultCode (), smsDTO );
3662 }
3763 }
3864
39- private void handleSentStatus (Context context , int resultCode , SMSDTO smsDTO ) {
65+ private void handleSentStatus (Context context , Intent intent , int resultCode , SMSDTO smsDTO ) {
4066 long timestamp = System .currentTimeMillis ();
4167 String errorMessage = "" ;
4268
@@ -47,76 +73,81 @@ private void handleSentStatus(Context context, int resultCode, SMSDTO smsDTO) {
4773 Log .d (TAG , "SMS sent successfully - ID: " + smsDTO .getSmsId ());
4874 break ;
4975 case SmsManager .RESULT_ERROR_GENERIC_FAILURE :
50- errorMessage = "Generic failure" ;
76+ errorMessage = "SMS failed on device. Common causes: no SMS credit on SIM, weak signal, or carrier blocked. Check SIM balance and signal, then try again." ;
77+ int radioCode = intent .getIntExtra ("errorCode" , -1 );
78+ if (radioCode != -1 ) {
79+ errorMessage += " (code " + radioCode + ")" ;
80+ }
5181 smsDTO .setStatus ("FAILED" );
5282 smsDTO .setFailedAtInMillis (timestamp );
5383 smsDTO .setErrorCode (String .valueOf (resultCode ));
5484 smsDTO .setErrorMessage (errorMessage );
5585 Log .e (TAG , "SMS failed to send - ID: " + smsDTO .getSmsId () + ", Error code: " + resultCode + ", Error: " + errorMessage );
5686 break ;
5787 case SmsManager .RESULT_ERROR_RADIO_OFF :
58- errorMessage = "Radio off" ;
88+ errorMessage = "Mobile radio is off (e.g. airplane mode). Turn off airplane mode and ensure cellular is on. " ;
5989 smsDTO .setStatus ("FAILED" );
6090 smsDTO .setFailedAtInMillis (timestamp );
6191 smsDTO .setErrorCode (String .valueOf (resultCode ));
6292 smsDTO .setErrorMessage (errorMessage );
6393 Log .e (TAG , "SMS failed to send - ID: " + smsDTO .getSmsId () + ", Error code: " + resultCode + ", Error: " + errorMessage );
6494 break ;
6595 case SmsManager .RESULT_ERROR_NULL_PDU :
66- errorMessage = "Null PDU " ;
96+ errorMessage = "Message could not be sent; invalid format or carrier issue. Try a shorter message or different recipient. " ;
6797 smsDTO .setStatus ("FAILED" );
6898 smsDTO .setFailedAtInMillis (timestamp );
6999 smsDTO .setErrorCode (String .valueOf (resultCode ));
70100 smsDTO .setErrorMessage (errorMessage );
71101 Log .e (TAG , "SMS failed to send - ID: " + smsDTO .getSmsId () + ", Error code: " + resultCode + ", Error: " + errorMessage );
72102 break ;
73103 case SmsManager .RESULT_ERROR_NO_SERVICE :
74- errorMessage = "No service" ;
104+ errorMessage = "No cellular service. Check signal and try again when you have coverage. " ;
75105 smsDTO .setStatus ("FAILED" );
76106 smsDTO .setFailedAtInMillis (timestamp );
77107 smsDTO .setErrorCode (String .valueOf (resultCode ));
78108 smsDTO .setErrorMessage (errorMessage );
79109 Log .e (TAG , "SMS failed to send - ID: " + smsDTO .getSmsId () + ", Error code: " + resultCode + ", Error: " + errorMessage );
80110 break ;
81111 case SmsManager .RESULT_ERROR_LIMIT_EXCEEDED :
82- errorMessage = "Sending limit exceeded " ;
112+ errorMessage = "Device/carrier send limit reached (too many SMS in a short time). Wait a few minutes or lower the send rate. " ;
83113 smsDTO .setStatus ("FAILED" );
84114 smsDTO .setFailedAtInMillis (timestamp );
85115 smsDTO .setErrorCode (String .valueOf (resultCode ));
86116 smsDTO .setErrorMessage (errorMessage );
87117 Log .e (TAG , "SMS failed to send - ID: " + smsDTO .getSmsId () + ", Error code: " + resultCode + ", Error: " + errorMessage );
88118 break ;
89119 case SmsManager .RESULT_ERROR_SHORT_CODE_NOT_ALLOWED :
90- errorMessage = "Short code not allowed" ;
120+ errorMessage = "Short code not allowed on this carrier. Use a full phone number. " ;
91121 smsDTO .setStatus ("FAILED" );
92122 smsDTO .setFailedAtInMillis (timestamp );
93123 smsDTO .setErrorCode (String .valueOf (resultCode ));
94124 smsDTO .setErrorMessage (errorMessage );
95125 Log .e (TAG , "SMS failed to send - ID: " + smsDTO .getSmsId () + ", Error code: " + resultCode + ", Error: " + errorMessage );
96126 break ;
97127 case SmsManager .RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED :
98- errorMessage = "Short code never allowed " ;
128+ errorMessage = "Short codes are not supported on this carrier. Use a full phone number. " ;
99129 smsDTO .setStatus ("FAILED" );
100130 smsDTO .setFailedAtInMillis (timestamp );
101131 smsDTO .setErrorCode (String .valueOf (resultCode ));
102132 smsDTO .setErrorMessage (errorMessage );
103133 Log .e (TAG , "SMS failed to send - ID: " + smsDTO .getSmsId () + ", Error code: " + resultCode + ", Error: " + errorMessage );
104134 break ;
105135 case SmsManager .RESULT_NETWORK_ERROR :
106- errorMessage = "Network error" ;
136+ errorMessage = "Network error while sending. Check signal and try again. " ;
107137 smsDTO .setStatus ("FAILED" );
108138 smsDTO .setFailedAtInMillis (timestamp );
109139 smsDTO .setErrorCode (String .valueOf (resultCode ));
110140 smsDTO .setErrorMessage (errorMessage );
111141 Log .e (TAG , "SMS failed to send - ID: " + smsDTO .getSmsId () + ", Error code: " + resultCode + ", Error: " + errorMessage );
112142 break ;
113143 default :
114- errorMessage = "Unknown error" ;
144+ String codeName = getResultCodeName (resultCode );
145+ errorMessage = codeName != null ? codeName : ("Unknown error (code " + resultCode + ")" );
115146 smsDTO .setStatus ("FAILED" );
116147 smsDTO .setFailedAtInMillis (timestamp );
117148 smsDTO .setErrorCode (String .valueOf (resultCode ));
118149 smsDTO .setErrorMessage (errorMessage );
119- Log .e (TAG , "SMS failed to send - ID: " + smsDTO .getSmsId () + ", Unknown error code : " + resultCode );
150+ Log .e (TAG , "SMS failed to send - ID: " + smsDTO .getSmsId () + ", Error : " + errorMessage );
120151 break ;
121152 }
122153
@@ -134,18 +165,19 @@ private void handleDeliveredStatus(Context context, int resultCode, SMSDTO smsDT
134165 Log .d (TAG , "SMS delivered successfully - ID: " + smsDTO .getSmsId ());
135166 break ;
136167 case Activity .RESULT_CANCELED :
137- errorMessage = "Delivery canceled" ;
168+ errorMessage = "Delivery report was canceled (e.g. carrier does not support delivery receipts). Message may still have been delivered. " ;
138169 smsDTO .setStatus ("DELIVERY_FAILED" );
139170 smsDTO .setErrorCode (String .valueOf (resultCode ));
140171 smsDTO .setErrorMessage (errorMessage );
141172 Log .e (TAG , "SMS delivery failed - ID: " + smsDTO .getSmsId () + ", Error code: " + resultCode + ", Error: " + errorMessage );
142173 break ;
143174 default :
144- errorMessage = "Unknown delivery error" ;
175+ String deliveryCodeName = getResultCodeName (resultCode );
176+ errorMessage = deliveryCodeName != null ? deliveryCodeName : ("Unknown delivery error (code " + resultCode + ")" );
145177 smsDTO .setStatus ("DELIVERY_FAILED" );
146178 smsDTO .setErrorCode (String .valueOf (resultCode ));
147179 smsDTO .setErrorMessage (errorMessage );
148- Log .e (TAG , "SMS delivery failed - ID: " + smsDTO .getSmsId () + ", Unknown error code : " + resultCode );
180+ Log .e (TAG , "SMS delivery failed - ID: " + smsDTO .getSmsId () + ", Error : " + errorMessage );
149181 break ;
150182 }
151183
0 commit comments