5

I am developing an application in which i need to send 100+ of messages. After going through few threads i came to know there is limitation on sending messages like 100 messages can be send in an hour. To do so i divide my recipient list into chunks and place delay of 5 seconds between each chunk and 3 seconds delay in every message. The delay between chunks increase after every chunk and when it gets to 100 seconds it will reset to 5 seconds. After that it worked OK for 50 messages but when i raise recipient list it causing issues some messages didn't go at first place and shown as error messages in native.

Is there any standard way to achieve this i may need to send 100+ messages , how can i send multiple messages without any failure at once. If i need to place delay what should be the appropriate delay between chunks or messages.

Thanks in advance.

private final int MAX_SMS_IN_ONE_TIME = 10;
private final int DELAY_BETWEEN_CHUNKS = 5000;

public void sendMessage(arguments){ 
    // Send long messages in chunk of 20 messages and put gap of increasing 5 seconds till 50 seconds and then reset.

    final Iterator iterator = messageChunks.iterator();
    new Thread(new Runnable() {
        @Override
        public void run(){

        int interval =1;
        while (iterator.hasNext()) {

            for (final Contact contact :
                (List<Contact>) iterator.next()) {

                sendSMS(body, contact.getmMobileNumbers().get(0));

                App.trackEvent("Message", "Sent", "Messages from our sms app");
            }
        }
        try {
            Log.i("chunk", "chunk # " + interval + " delay is " + DELAY_BETWEEN_CHUNKS);
            Thread.sleep(DELAY_BETWEEN_CHUNKS * interval);
            interval++;
            if (interval == 10) {
                interval = 1;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        }
        }
    }).start();
}

public void sendSMS(final String message, final String phoneNo) {
    try {
        String SENT = "com.ebryx.smscustommessagegeneration"+""+System.currentTimeMillis()+""+((int)this.getmMessageId());
        Intent intentMessageASendStatus = new Intent(SENT);

        final PendingIntent pi = PendingIntent.getBroadcast(App.getContext(),  ((int)this.getmMessageId()),
                intentMessageASendStatus, PendingIntent.FLAG_CANCEL_CURRENT);
        final ArrayList<PendingIntent> sentPI = new ArrayList<PendingIntent>(){{add(pi);}};

        App.getContext().registerReceiver(new BroadcastReceiver(){
            @Override
            public void onReceive(Context arg0, Intent arg1) {


                switch (getResultCode())
                {
                    case Activity.RESULT_OK:

                        Log.i("tag","sent successfully ");
            break;
                    case SmsManager.RESULT_ERROR_GENERIC_FAILURE:

                        Log.i("tag","Generic Failure");
                break;

                    case SmsManager.RESULT_ERROR_NO_SERVICE:

                        Log.i("tag","No service failure");
            break;

        case SmsManager.RESULT_ERROR_NULL_PDU:
                        break;
                    case SmsManager.RESULT_ERROR_RADIO_OFF:

                        Log.i("tag","Airplane mode failure");
                        break;
                }
            }
        }, new IntentFilter(SENT));

        final SmsManager smsManager = SmsManager.getDefault();
        final ArrayList<String> parts = smsManager.divideMessage(message);

        new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    smsManager.sendMultipartTextMessage(phoneNo, null, parts, sentPI, null);

                }}, 3000);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Hassan Munir
  • 379
  • 6
  • 22

2 Answers2

4

You should use two broadcast receiver with pending intent for SENT and DELIVER.

After message delivers you have to add callback mechanism to notify msg has been delivered and stat sending new message. This call should be synchronized.

  1. Create a HashMap, and send to below method one by one according to status of delivery which we are getting in below delivery broadcast receiver.

        /**
         * Sends an SMS message to another device
         * 
         * @param phoneNumber Number to which msg send
         * @param message Text message
         */
    private void sendSMS(String phoneNumber, String message) {
        // Intent Filter Tags for SMS SEND and DELIVER
        String SENT = "SMS_SENT";
        String DELIVERED = "SMS_DELIVERED";
    // STEP-1___
        // SEND PendingIntent
        PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(
                SENT), 0);
    
        // DELIVER PendingIntent
        PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0,
                new Intent(DELIVERED), 0);
    // STEP-2___
        // SEND BroadcastReceiver
        BroadcastReceiver sendSMS = new BroadcastReceiver() {
            @Override
            public void onReceive(Context arg0, Intent arg1) {
                switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "SMS sent",
                            Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    Toast.makeText(getBaseContext(), "Generic failure",
                            Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    Toast.makeText(getBaseContext(), "No service",
                            Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    Toast.makeText(getBaseContext(), "Null PDU",
                            Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    Toast.makeText(getBaseContext(), "Radio off",                            Toast.LENGTH_SHORT).show();
                    break;
                }
            }
        };
    
        // DELIVERY BroadcastReceiver
        BroadcastReceiver deliverSMS = new BroadcastReceiver() {
            @Override
            public void onReceive(Context arg0, Intent arg1) {
                switch (getResultCode()) {
                case Activity.RESULT_OK:
                     // TODO : notify from here to send new message.
                     // Add callback mechanism 
                    Toast.makeText(getBaseContext(), "SMS delivered",
                            Toast.LENGTH_SHORT).show();
                    break;
                case Activity.RESULT_CANCELED:
                    Toast.makeText(getBaseContext(), "SMS not delivered",
                            Toast.LENGTH_SHORT).show();
                    break;
                }
            }
        };
    // STEP-3___
        // ---Notify when the SMS has been sent---
        registerReceiver(sendSMS, new IntentFilter(SENT));
    
        // ---Notify when the SMS has been delivered---
        registerReceiver(deliverSMS, new IntentFilter(DELIVERED));
    
        SmsManager sms = SmsManager.getDefault();
        sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
     }
    }
    
  2. You can also remove elements from your HashMap as your SMS DELIVERED This could be helpful for you to track how many messages are delivered successfully.
Jitesh Mohite
  • 24,460
  • 12
  • 119
  • 117
  • Thanks for your answer @jitesh appreciate it. But i read on another answer that "At & T mobiles does not support message delivery report". I have tested on Lg g3 and Samsung S5 on both phones delivery broadcast receier not called. So put business logic on it is risky thing to do. – Hassan Munir Aug 28 '17 at 07:55
  • while investigating it i came across there is predefined limit to send messages in time , like 100 msgs per hour and 30 msgs per half hour. To avoid this you need to root the phone and change that limit. After reading it i consider the messages that send failed may be its reason is the limit correct my if i am wrong. please share ur thoughts on it. link is folllowing : https://stackoverflow.com/questions/19079151/is-there-a-limit-to-the-number-of-numbers-to-send-an-sms – Hassan Munir Aug 28 '17 at 07:59
1

There appears to be no official documentation for SMS send limits, from what I could find and the following site either.

Unfortunately there appears to be no public documentation from Google’s Android development team on the issue.

This is from May 17, 2017

The only figures on sms limits I've been able to find are from Commonsware's site:

SMS Sending Limitations
Apps running on Android 1.x and 2.x devices are limited to sending 100 SMS messages an hour, before the user starts getting prompted with each SMS message request to confirm that they do indeed wish to send it.

Apps running on Android 4.x devices, the limits are now 30 SMS messages in 30 minutes .../...

There appears to be no way around increasing that limit without rooting the phone. Where you need to change the following settings. The following will allow 1000 SMS to be sent per 180000ms == 30 minutes.

SMS_OUTGOING_CHECK_MAX_COUNT 1000
SMS_OUTGOING_CHECK_INTERVAL_MS 1800000

The usual (frustrating) Android issues with varying performance across devices also applies. One phone may perform at a different level to another.

This company has determined the maximum SMS capacities for some handsets with their product. SMS sending limits with FrontlineSync and Android. They also advise that rooting the phone may be needed to increase limits.

Related resources:

Check android package SMS limit?

is there a limit to the number of numbers to send an SMS?

Android Java: How To Send SMS & Receive SMS & Get SMS Messages dated 30 August, 2017.