Send SMS until

I am trying to send an urgent SMS from my application. I have to make sure that the SMS message was sent successfully.

SMS is sent after loading the Android system and after checking.

So I have a class of service that handles the BOOT_COMPLETED recycling filter. This class performs a check, and if something is true, then it tries to send an SMS message through another class that "extends the service"

After it is successfully sent sms, both services (the one that processes the boot call and the one that sends the SMS) should exit.

Question 1 . How to force the sms send function to be called with a timeout without receiving an application immunity message? I am currently using this (I don't know if this is the right thing to do, although it works):

Timer mTimer = new Timer();
//wait a small timeout prior to sending the message.
mTimer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        this.cancel(); //I don't want to run the timer more than once
        sms_sender sms = new sms_sender();
        sms.sendSMS(phoneNumber, messageText);
    }
}, 30000, 30000); //run sendSMS() after 30 seconds

Question 2 : How to implement the sendSMS function to retry every 30 seconds after realizing that the last attempt was unsuccessful?

Question 3 . How to stop both services after I realized that the SMS was sent successfully?

This is my code that does not work:

public class sms_sender extends Service {

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    final String SENT = "SMS_SENT";

    public void sendSMS(final String phoneNumber, final String message, final boolean check_result)
    {

        PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0);
        registerReceiver(new BroadcastReceiver(){
            @Override
            public void onReceive(Context arg0, Intent arg1) {
                if(!check_result)
                    return;
                switch (getResultCode())
                {
                    case Activity.RESULT_OK:
                        //exit
                        stopSelf();
                        return;
                    case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    case SmsManager.RESULT_ERROR_NO_SERVICE:
                    case SmsManager.RESULT_ERROR_NULL_PDU:
                    case SmsManager.RESULT_ERROR_RADIO_OFF:
                        //try again in 1 minute
                        Timer mTimer = new Timer();
                        mTimer.scheduleAtFixedRate(new TimerTask() {
                            @Override
                            public void run() {
                                this.cancel(); //no need to run again, if it fails, this exact code will run again
                                sendSMS(phoneNumber, message, true);
                            }
                        }, 60000, 60000);
                        return;
                }
            }
        }, new IntentFilter(SENT));

        SmsManager smsManager = SmsManager.getDefault();
        smsManager.sendTextMessage(phoneNumber, null, message, sentPI, null);
    }
}

Currently, the program crashes from a PendingIntent call. I tried to implement BroadCastReceiver in the onCreate method using private member variables to call the sendSMS () function again using the onReceive method, but onReceive never ran.

- EDIT -

, . , , . , . SMS-, .

. :

public class service extends Service{

    static public service serv;
    //member variable. Initializing to null so as to know whether to unregister the service or not
    private BroadcastReceiver messageSent = null;

    ...
    ...
    @Override
    public void onStart(Intent intent, int startid)
    {
    serv=this; //will use this static variable in order to shutdown the service when the message is successfully sent
    ...
    ...
        if(somethingIsTrue()){
            //register receiver
            messageSent = new sent_message();
            registerReceiver(messageSent, new IntentFilter(sms_sender.INTENT_MESSAGE_SENT));
            startMessageServiceIntent(messageText, phoneNumber); //function code can be found on accepted answer
        }
    }
}

sent_message :

public class sent_message extends BroadcastReceiver {

    private Context pubCon;

    private void startMessageServiceIntent(String message, String receiver) {
        Intent i = new Intent(pubCon, sms_sender.class);
        i.putExtra(sms_sender.EXTRA_MESSAGE, message);
        i.putExtra(sms_sender.EXTRA_RECEIVERS, new String[] { receiver });
        pubCon.startService(i);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        pubCon=context;
        switch (getResultCode()) {
            case Activity.RESULT_OK:
                    //all went OK, stop the service where this is called from
                service.serv.stopSelf();
                break;
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
            case SmsManager.RESULT_ERROR_NO_SERVICE:
            case SmsManager.RESULT_ERROR_NULL_PDU:
            case SmsManager.RESULT_ERROR_RADIO_OFF:
                    //try sending the message again after 30s
                new Handler().postDelayed(new Runnable(){
                    @Override
                    public void run(){
                        startMessageServiceIntent(service.messageText, service.phoneNumber);
                    }
                }, 30000);

                break;
        }

    }
}

( ) sms_sender :

public class sms_sender extends IntentService {

    public static final String INTENT_MESSAGE_SENT = "message.sent";
    public static final String INTENT_MESSAGE_DELIVERED = "message.delivered";

    public static final String EXTRA_MESSAGE = "extra.message";
    public static final String EXTRA_RECEIVERS = "extra.receivers";

    public sms_sender() {
        super("sms_sender");
    }

    private static class IDGenerator {

        private static final AtomicInteger counter = new AtomicInteger();

        public static int nextValue() {
            return counter.getAndIncrement();
        }
    }

    public void sendSMS(String message, String receiver) {
        SmsManager sm = SmsManager.getDefault();

        PendingIntent sentPI = null;

        Intent sentIntent = new Intent(INTENT_MESSAGE_SENT);

        int sentID = IDGenerator.nextValue();
        sentPI = PendingIntent.getBroadcast(sms_sender.this, sentID, sentIntent,
                PendingIntent.FLAG_CANCEL_CURRENT);

        try {
            sm.sendTextMessage(receiver, null, message, sentPI, null);
        } catch (IllegalArgumentException e) {
            System.out.println("Illegal argument");
        }
    }

    protected void onHandleIntent(Intent intent) {
        String message = intent.getStringExtra(EXTRA_MESSAGE);
        String[] receivers = intent.getStringArrayExtra(EXTRA_RECEIVERS);
        sendSMS(message, receivers[0]);
    }
}
+4
1

:

public class SMSSender extends IntentService {

public static final String INTENT_MESSAGE_SENT = "message.sent";
public static final String INTENT_MESSAGE_DELIVERED = "message.delivered";

public static final String EXTRA_MESSAGE = "extra.message";
public static final String EXTRA_RECEIVERS = "extra.receivers";

public SMSSender() {
    super("SMSSender");
}

private final String TAG = "SendSMS";


private static class IDGenerator {

    private static final AtomicInteger counter = new AtomicInteger();

    public static int nextValue() {
        return counter.getAndIncrement();
    }
}

private void sendSMS(String message, String[] receivers) {

    SmsManager sm = SmsManager.getDefault();

    ArrayList<String> parts = sm.divideMessage(message);

    PendingIntent sentPI = null;
    PendingIntent deliveredPI = null;

    Intent sentIntent = new Intent(INTENT_MESSAGE_SENT);

    int sentID = IDGenerator.nextValue();
    sentPI = PendingIntent.getBroadcast(SMSSender.this, sentID, sentIntent,
            PendingIntent.FLAG_CANCEL_CURRENT);

    Intent deliveryIntent = new Intent(INTENT_MESSAGE_DELIVERED);

    int deliveredID = IDGenerator.nextValue();
    deliveredPI = PendingIntent.getBroadcast(SMSSender.this, deliveredID,
            deliveryIntent, PendingIntent.FLAG_CANCEL_CURRENT);

    Log.i(TAG, "sending SMS: parts: " + parts.size() + " message: "
            + message);

    if (parts.size() > 1) {
        ArrayList<PendingIntent> sentIntents = null;
        ArrayList<PendingIntent> deliveredIntents = null;

        sentIntents = new ArrayList<PendingIntent>();
        deliveredIntents = new ArrayList<PendingIntent>();

        for (int i = 0; i < parts.size(); i++) {
            sentIntents.add(sentPI);
            deliveredIntents.add(deliveredPI);
        }

        for (String receiver : receivers) {
            try {
                sm.sendMultipartTextMessage(receiver, null, parts,
                        sentIntents, deliveredIntents);
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "illegal receiver: " + receiver);
            }

        }
    } else {
        for (String receiver : receivers) {
            try {
                sm.sendTextMessage(receiver, null, parts.get(0), sentPI,
                        deliveredPI);
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "illegal receiver: " + receiver);
            }
        }
    }
}

@Override
protected void onHandleIntent(Intent intent) {
    String message = intent.getStringExtra(EXTRA_MESSAGE);
    String[] receivers = intent.getStringArrayExtra(EXTRA_RECEIVERS);

    sendSMS(message, receivers);

}

:

    private void startMessageServiceIntent(String message, String receiver) {
        Intent i = new Intent(context, SMSSender.class);
        i.putExtra(SMSSender.EXTRA_MESSAGE, message);
        i.putExtra(SMSSender.EXTRA_RECEIVERS, new String[] { receiver });
        startService(i)
    }

, , / .

:

<uses-permission android:name="android.permission.SEND_SMS" />

<service android:name="your.package.SMSSender" android:enabled="true" />

, / :

@Override
protected void onCreate() {

    ...

    // ---when the SMS has been sent---
    private BroadcastReceiver messageSent; // <- stored as a field
    messageSent = new SentMessage(); 
    registerReceiver(messageSent, new IntentFilter(SMSSender.INTENT_MESSAGE_SENT));

    // ---when the SMS has been delivered---
    private BroadcastReceiver messageDelivered; // <- stored as a field
    messageDelivered = new MessageDelivered();
    registerReceiver(messageDelivered, new IntentFilter(
            SMSSender.INTENT_MESSAGE_DELIVERED));
}

@Override
protected void onDestroy() { // remember to unregister
    unregisterReceiver(messageSent);
    unregisterReceiver(messageDelivered );
}

, , , .

: messageSent messageDelivered

, , , .

:

public class SentMessage extends BroadcastReceiver {

private final String TAG = "SentMessage";

@Override
public void onReceive(Context context, Intent intent) {
    long _id = intent.getLongExtra(EXTRA_ID, -1);
    long protocol_id = intent.getLongExtra(EXTRA_PROTOCOL, -1);
    Log.d(TAG, "SentMessage");
    switch (getResultCode()) {
    case Activity.RESULT_OK:
        Log.d(TAG, "RESULT_OK");
        if (MessageData.sentMessage(_id, protocol_id)) {
            try {
                Database.messageSent(_id);
            } catch (DatabaseRowNotFoundException e) {
                Log.e(TAG, e.toString(), e);
            }
        }
        break;
    case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
        Log.d(TAG, "RESULT_ERROR_GENERIC_FAILURE");
        MessageData.postponeMessage(_id);
        ApplicationData.hasSignal(false);
        break;
    case SmsManager.RESULT_ERROR_NO_SERVICE:
        Log.d(TAG, "RESULT_ERROR_NO_SERVICE");
        MessageData.postponeMessage(_id);
        ApplicationData.hasSignal(false);
        break;
    case SmsManager.RESULT_ERROR_NULL_PDU:
        Log.d(TAG, "RESULT_ERROR_NULL_PDU");
        break;
    case SmsManager.RESULT_ERROR_RADIO_OFF:
        Log.d(TAG, "RESULT_ERROR_RADIO_OFF");
        MessageData.postponeMessage(_id);
        ApplicationData.hasSignal(false);
        break;
    }

}

:

public class DeliveredMessage extends BroadcastReceiver {

private final String TAG = "DeliveredMessage ";


@Override
public void onReceive(Context context, Intent intent) {

    long _id = intent.getLongExtra(EXTRA_ID, -1);
    long protocol_id = intent.getLongExtra(EXTRA_PROTOCOL, -1);
    switch (getResultCode()) {
    case Activity.RESULT_OK:
        if (_id != -1 && MessageData.deliveredMessage(_id, protocol_id)) {
            try {
                Database.messageDelivered(_id);
                Cursor messageCursor = Database.getCursorByID(MessageOutboxContentProvider.CONTENT_URI, MessageOutboxContentProvider._ID, _id);
                messageCursor.close();
            } catch (DatabaseRowNotFoundException e) {
                Log.e(TAG, e.toString(), e);
            }
        }
        break;
    case Activity.RESULT_CANCELED:
        break;
    }
}

}

, , . , , - .

GCM SMS , .

Edit2: , , :

1: IntentService .

, , :

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            // send sms
        }
    }, delay);

2: , , . , , , /.

3: , Intent Service. , , , , . , .

+8

All Articles