You cannot catch
a sent or delivery success/failure, as it is not an Exception
, nor any other type of Throwable
.
You will need to create PendingIntent
s for sent and delivered actions, and pass them in the method used to send the SMS. The following is an example that can be used for single or multipart messages.
public static final String ACTION_SMS_SENT = "com.mycompany.myapp.SMS_SENT";
public static final String ACTION_SMS_DELIVERED = "com.mycompany.myapp.SMS_DELIVERED";
private void sendSMS(String number, String message) {
final SmsManager sm = SmsManager.getDefault();
final ArrayList<String> parts = sm.divideMessage(message);
final int ct = parts.size();
final ArrayList<PendingIntent> sentPis = new ArrayList<PendingIntent>(ct);
final ArrayList<PendingIntent> delPis = new ArrayList<PendingIntent>(ct);
for (int i = 0; i < ct; i++) {
final PendingIntent piSent =
PendingIntent.getBroadcast(this,
i,
new Intent(ACTION_SMS_SENT),
0);
final PendingIntent piDel =
PendingIntent.getBroadcast(this,
i,
new Intent(ACTION_SMS_DELIVERED),
0);
sentPis.add(piSent);
delPis.add(piDel);
}
sm.sendMultipartTextMessage(number, null, parts, sentPis, delPis);
}
You will need to register a BroadcastReceiver
to get the results. A basic Receiver example:
public class SmsResultReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ACTION_SMS_SENT)) {
switch (getResultCode()) {
case -1: //Activity.RESULT_OK
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
break;
default:
}
}
else if (action.equals(ACTION_SMS_DELIVERED)) {
switch (getResultCode()) {
case -1: //Activity.RESULT_OK
break;
case 0: //Activity.RESULT_CANCELED
break;
default:
}
}
}
}
Do note that each Receiver will be run once for each message part. I would also mention that not all carriers provide delivery reports, so there's no guarantee that the delivered PendingIntent
s will ever fire.
An instance of this Receiver can be registered dynamically with the Context#registerReceiver()
method, or the Receiver class can be registered in the manifest with a <receiver>
element, and the appropriate <intent-filter>
s.