DreamBigAlvin DreamBigAlvin - 5 months ago 16
Android Question

Android sms getting the response error/notification if the message has been delivered or sent successfully

How can i get the error when sending message and the response when the message has been successfully sent?


Here is my code:

try {
String message = "Hello World! Now we are going to demonstrate " +
"how to send a \n message with more than \n 160 characters from your Android application.";
SmsManager smsManager = SmsManager.getDefault();
ArrayList<String> parts = smsManager.divideMessage(message );
smsManager.sendMultipartTextMessage(phoneNumber, null, parts, null, null);
} catch (Exception e) {
//HOW CAN I GET THE SMS RESPONES HERE
Toast.makeText(context, "SMS faild!",Toast.LENGTH_LONG).show();
e.printStackTrace();
}

Answer

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 PendingIntents 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 PendingIntents 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.

Comments