Отправка более 50 сообщений, вызывающих проблемы, приводит к общему сбою

Я разрабатываю приложение, в котором мне нужно отправить более 100 сообщений. Пройдя через несколько тем, я узнал, что существует ограничение на отправку сообщений, например, 100 сообщений можно отправить за час. Для этого я делю свой список получателей на куски и помещаю задержку в 5 секунд между каждым фрагментом и задержку в 3 секунды в каждом сообщении. Задержка между фрагментами увеличивается после каждого фрагмента, и когда она достигает 100 секунд, она сбрасывается до 5 секунд. После этого он работал нормально для 50 сообщений, но когда я поднимаю список получателей, это вызывает проблемы, некоторые сообщения не идут на первом месте и отображаются как сообщения об ошибках в родном.

Есть ли какой-либо стандартный способ добиться этого, мне может потребоваться отправить более 100 сообщений, как я могу отправить несколько сообщений без каких-либо сбоев одновременно. Если мне нужно установить задержку, какой должна быть соответствующая задержка между фрагментами или сообщениями.

Заранее спасибо.

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();
    }
}

person Hassan Munir    schedule 22.08.2017    source источник
comment
Какое сообщение об ошибке вы видите?   -  person Scott Newson    schedule 25.08.2017
comment
@ScottNewson, я не вижу никаких сообщений об ошибках, но несколько сообщений не отправились из-за общего сбоя.   -  person Hassan Munir    schedule 28.08.2017


Ответы (2)


Вы должны использовать два широковещательных приемника с ожидающими намерениями для SENT и DELIVER.

После доставки сообщения вы должны добавить механизм обратного вызова, чтобы уведомить о доставке сообщения и отправить новое сообщение. Этот вызов должен быть синхронизирован.

  1. Создайте HashMap и отправьте по одному методу ниже в соответствии со статусом доставки, который мы получаем в получателе широковещательной рассылки ниже.

        /**
         * 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. Вы также можете удалить элементы из HashMap как SMS DELIVERED. Это может быть полезно для отслеживания количества успешно доставленных сообщений.
person Jitesh Mohite    schedule 26.08.2017
comment
Спасибо за ваш ответ @jitesh ценю это. Но я прочитал в другом ответе, что мобильные телефоны At & T не поддерживают отчет о доставке сообщений. Я тестировал на Lg g3 и Samsung S5, на обоих телефонах приемник вещания доставки не вызывался. Так что ставить бизнес-логику на это рискованно. - person Hassan Munir; 28.08.2017
comment
исследуя это, я обнаружил, что существует предопределенный лимит на отправку сообщений по времени, например, 100 сообщений в час и 30 сообщений в полчаса. Чтобы избежать этого, вам нужно рутировать телефон и изменить это ограничение. Прочитав его, я считаю, что сообщения, которые отправляются не удалось, могут быть причиной того, что предел исправьте, если я ошибаюсь. пожалуйста, поделитесь своими мыслями по этому поводу. ссылка следующая: stackoverflow.com/questions/19079151/ - person Hassan Munir; 28.08.2017

Судя по тому, что я смог найти, а также на следующем сайте, официальной документации по ограничениям на отправку SMS не существует.

К сожалению Похоже, что по этому вопросу нет общедоступной документации от команды разработчиков Google Android.

Это от 17 мая 2017 г.

Единственные данные об ограничениях на SMS, которые мне удалось найти, взяты с сайта Commonsware:

Ограничения на отправку SMS
Приложения, работающие на Устройства Android 1.x и 2.x ограничены отправкой 100 SMS-сообщений в час, прежде чем пользователь начнет получать запрос с каждым запросом SMS-сообщения, чтобы подтвердить, что он действительно хочет его отправить.

Приложения, работающие на устройствах Android 4.x, теперь ограничения составляют 30 SMS-сообщений за 30 минут .../...

Похоже, нет возможности увеличить этот лимит без рутирования. телефон. Где вам нужно изменить следующие настройки. Следующее позволит отправлять 1000 SMS за 180000 мс == 30 минут.

SMS_OUTGOING_CHECK_MAX_COUNT 1000
SMS_OUTGOING_CHECK_INTERVAL_MS 1800000

Обычные (разочаровывающие) проблемы Android с разной производительностью на разных устройствах также применимы. Один телефон может работать на другом уровне по сравнению с другим.

Эта компания определила максимальную емкость SMS для некоторых телефонов в своем продукте. Ограничения на отправку SMS с FrontlineSync и Android. Они также сообщают, что для увеличения лимитов может потребоваться рутирование телефона.

Связанные ресурсы:

Проверить лимит SMS для пакета Android?

существует ли ограничение на количество номеров для отправки SMS?

Android Java: как отправить SMS, получение SMS и получение SMS-сообщений от 30 августа 2017 года.

person Community    schedule 01.09.2017