Search code examples
javaandroidservicebroadcastreceiversmsmanager

Sending SMS from Intent Service - Unable to recieve broadcast to check if sms was sent


my app is about geofencing. When geofence is triggered, I need to send an SMS.

It works almost perfect, but I can't receive the Broadcast to check if SMS was sent. I will explain myself:

When user enters the geofence, a Geofence Intent Service is called, and it sends the sms. It works like a charm, but I need to make sure if the SMS has been sent, or there has been any trouble (i.e. no signal) and try to send it again.

So, first I have tried to send the sms this way:

    private void sendsms() {

        String SMS_SENT = "SMS_SENT";
        final PendingIntent sentPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);

// check if SMS has been sent
        smsSentReceiver =new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                switch (getResultCode()) {
                    case Activity.RESULT_OK:
                        Log.e("SMS", "SMS sent successfully");
                        break;
                    case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                        Log.e("SMS","Generic failure cause");
                        break;
                    case SmsManager.RESULT_ERROR_NO_SERVICE:
                        Log.e("SMS", "Service is currently unavailable");
                        break;
                    case SmsManager.RESULT_ERROR_NULL_PDU:
                        Log.e("SMS", "No pdu provided");
                        break;
                    case SmsManager.RESULT_ERROR_RADIO_OFF:
                        Log.e("SMS", "Radio was explicitly turned off");
                        break;
                }
            }
        };


        registerReceiver(smsSentReceiver, new Intent());

        // Get the default instance of SmsManager
        // Send a text based SMS
        SmsManager smsMgr = SmsManager.getDefault();
        smsMgr.sendTextMessage(towhom, null, customtxt, sentPendingIntent, null);

This works, but nothing happens after sms was sent, no log at all.

Then I tried this other way, creating the receiver and putting in the manifest:

private smsSentReceiver smsSentReceiver;

private void sendsms() {

        final PendingIntent sentPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);

        smsSentReceiver = new smsSentReceiver();
        registerReceiver(smsSentReceiver, new IntentFilter());

        // Get the default instance of SmsManager
        // Send a text based SMS
        SmsManager smsMgr = SmsManager.getDefault();
        smsMgr.sendTextMessage(towhom, null, customtxt, sentPendingIntent, null);

And this is smsSentReceiver.java

public class smsSentReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        switch (getResultCode()) {
            case Activity.RESULT_OK:
                Log.e("SMS", "SMS sent successfully");
                break;
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                Log.e("SMS","Generic failure cause");
                break;
            case SmsManager.RESULT_ERROR_NO_SERVICE:
                Log.e("SMS", "Service is currently unavailable");
                break;
            case SmsManager.RESULT_ERROR_NULL_PDU:
                Log.e("SMS", "No pdu provided");
                break;
            case SmsManager.RESULT_ERROR_RADIO_OFF:
                Log.e("SMS", "Radio was explicitly turned off");
                break;
        }
    }
}

And Manifest:

<receiver
            android:name=".smsSentReceiver"
            android:enabled="true"
            >

        </receiver>

No log at all either about sms status...

Any ideas about why I am not getting the sms status?

PS: Have only tested on emulator

Edit:

Last thing I've tried is this, according to @Mike M. comment:

private void sendsms() {

        final PendingIntent sentPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, smsSentReceiver.class), PendingIntent.FLAG_CANCEL_CURRENT);

 SmsManager smsMgr = SmsManager.getDefault();
        smsMgr.sendTextMessage(towhom, null, customtxt, sentPendingIntent, null);

And still nothing...


Solution

  • An IntentService will stop itself as soon as it's finished its work, and any Receivers dynamically registered on it go away, as well. In your first snippet, the Receiver likely won't be alive to receive the broadcast when it's finally sent, as the sendTextMessage() call will return immediately, and the PendingIntent will be fired asynchronously.

    Statically registering the Receiver class, as you've done in the second snippet, will allow the Receiver to get the broadcast even after the IntentService has died, as the resulting Receiver instance will not be tied to it. However, the Intent you've used for the PendingIntent does not correctly target the Receiver class. Change it to new Intent(this, smsSentReceiver.class).

    Lastly, logs with certain tags are suppressed, for some reason, and the "SMS" tag (exactly) is one of those. Change that tag to something not listed there; e.g., "smsSentReceiver".