Поведение SMS-уведомлений - PullRequest
2 голосов
/ 13 марта 2012

обзвон Сейчас я пытаюсь отправить SMS программным способом, используя следующий код, но я не понимаю, как поступает SMS SENT Receiver.

1) например, если я отправлю одно SMS, то Activity.RESULT_OK внутри registerReceiver вызывается 3 раза. и если я отправлю 3 SMS с помощью для петлевого вызова sendSMS, тогда Activity.RESULT_OK звонил 9 раз. теперь я действительно не знаю, для одного смс, чтобы отправить, почему это registerReceiver вызывается так много раз?

2) Более того, когда я запускаю этот код поверх эмулятора, я передаю эмулятор порт для отправки SMS на другие эмуляторы, что естественно, но когда я пытаюсь отправить смс на реальный номер, то я не получаю сообщение об ошибке доставки уведомление, так как оно уведомляет Activity.RESULT_OK только

код для отправки SMS

private void sendSMS(String phoneNumber, String message)
        {      

            String SENT = "SMS_SENT";
            String DELIVERED = "SMS_DELIVERED";

            PendingIntent sentPI = PendingIntent.getBroadcast(this, 0,
                new Intent(SENT), 0);

            PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0,
                new Intent(DELIVERED), 0);
            Log.d("SMS Service", "SMS SEND CALLED");
            //---when the SMS has been sent---
            registerReceiver(new BroadcastReceiver(){
                @Override
                public void onReceive(Context arg0, Intent arg1) {

                    Log.d("SMS Service", "RECEIVE CALLED");
                    switch (getResultCode())
                    {
                        case Activity.RESULT_OK:
                            Toast.makeText(SMSService.this, "SMS sent", 
                                    Toast.LENGTH_SHORT).show();
                            System.out.println("SMSService " + "SMS SENT");
                            break;
                        case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                            Toast.makeText(SMSService.this, "Generic failure", 
                                    Toast.LENGTH_SHORT).show();
                            System.out.println("SMSService " + "GENERIC FAILURE");                          
                            break;
                        case SmsManager.RESULT_ERROR_NO_SERVICE:
                            Toast.makeText(SMSService.this, "No service", 
                                    Toast.LENGTH_SHORT).show();
                            System.out.println("SMSService " + "NO SERVICE");
                            break;
                        case SmsManager.RESULT_ERROR_NULL_PDU:
                            Toast.makeText(SMSService.this, "Null PDU", 
                                    Toast.LENGTH_SHORT).show();
                            System.out.println("SMSService " + "Null PDU");
                            break;
                        case SmsManager.RESULT_ERROR_RADIO_OFF:
                            Toast.makeText(SMSService.this, "Radio off", 
                                    Toast.LENGTH_SHORT).show();
                            System.out.println("SMSService " + "Radio Off");
                            break;

                    }
                }
            }, new IntentFilter(SENT));

            //---when the SMS has been delivered---
            registerReceiver(new BroadcastReceiver(){
                @Override
                public void onReceive(Context arg0, Intent arg1) {
                    switch (getResultCode())
                    {
                        case Activity.RESULT_OK:
                            Toast.makeText(getBaseContext(), "SMS delivered", 
                                    Toast.LENGTH_SHORT).show();
                            System.out.println("SMSService " + "SMS Delivered");
                            break;
                        case Activity.RESULT_CANCELED:
                            Toast.makeText(getBaseContext(), "SMS not delivered", 
                                    Toast.LENGTH_SHORT).show();
                            System.out.println("SMSService " + "SMS not delivered");                            
                            break;                      
                    }
                }
            }, new IntentFilter(DELIVERED));        

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

Ответы [ 2 ]

6 голосов
/ 13 марта 2012

Как правило, это зависит от размера отправляемого сообщения - если сообщение превышает лимит одного сообщения (и в вашем случае это звучит примерно в 3 раза больше лимита одного сообщения), вы получите отправку иотчет о доставке для каждой части сообщения.Поскольку вы не разделяете сообщение вручную, вы не можете указать разные намерения для каждой части.

Стоит взглянуть на SmsManager.divideMessage () , чтобы разделить сообщение самостоятельно изатем в SmsManager.sendMultiPartTextMessage () для фактической отправки.Это позволяет вам указать разные ожидающие намерения для разных частей сообщения, и, таким образом, вы можете определить, когда сообщение было окончательно отправлено.

Я думаю, что эмулятор обрабатывает все пункты назначения сообщений как точные и, поскольку нет сети длявернитесь и скажите, что в противном случае вы, скорее всего, не получите сообщение об ошибке отправки из эмулятора (если вы не сделали что-то вроде перевода эмулятора в режим полета).Из опыта вы наверняка получаете эти коды ошибок на реальном устройстве.

Редактировать: Думая об этом, вы также регистрируете получателя каждый раз, когда отправляете сообщение, код, который я использую, имеетманифест зарегистрированного получателя.Существует вероятность того, что вы зарегистрировали его несколько раз (он длится столько времени, сколько требуется для контекста, который вы регистрируете), что дало бы его вам несколько раз - это также заставило бы его повторить, вероятно, 9 раз для 3 сообщений (при условии регистрациив третий раз сделал это до того, как отправка была завершена для первого) - возможно, но я не знаю, насколько вероятно.Вы можете сравнительно хорошо протестировать, зарегистрировав объект в зарегистрированном получателе.

Это сокращенная версия кода, который я использую для отправки смс-сообщений, он не получает повторных ответов на сообщения:

ArrayList<String> split = SmsManager.getDefault().divideMessage(message);
ArrayList<PendingIntent> success = new ArrayList<PendingIntent>(partInfo.length);
Intent sendInt = null;
for (int i = 0; i < partInfo.length; i++)
{
   sendInt = new Intent(context.getPackageName() + RELAY_INTERNAL_RESPONSE);
   sendInt.putExtra(KEY_MESSAGEID, messageID);
   sendInt.putExtra(KEY_PART_NUMBER, i);
   sendInt.putExtra(KEY_REPLY_SEND_INTENT, sendIntAction);
   sendInt.putExtra(KEY_NUMBER, number);
   PendingIntent sendResult = PendingIntent.getBroadcast(context, i, sendInt, PendingIntent.FLAG_ONE_SHOT); //You have to use an incrementing request code to ensure you don't just get the same pending intent.
   success.add(sendResult);
}
ArrayList<PendingIntent> receipt = new ArrayList<PendingIntent>(partInfo.length);
sendInt = new Intent(context.getPackageName() + RELAY_INTERNAL_RECEIPT);
sendInt.putExtra(KEY_MESSAGEID, messageID);
sendInt.putExtra(KEY_REPLY_RECEIPT_INTENT, receiptIntAction);
sendInt.putExtra(KEY_NUMBER, number);
PendingIntent sendResult = PendingIntent.getBroadcast(context, nextReceiptCounter(context), sendInt, PendingIntent.FLAG_ONE_SHOT);
for (int i = 0; i < partInfo.length; i++)
{
   receipt.add(sendResult);
}
SmsManager sm = SmsManager.getDefault();
sm.sendMultipartTextMessage(target, null, split, success, receipt);

И мое определение получателя:

<receiver android:name="<package>.SMSBroadcastModule" 
      android:enabled="true" 
      android:exported="false">
      <intent-filter>
                <action android:name="<package>.RELAY_INTERNAL_RESPONSE" />
                <action android:name="<package>.RELAY_INTERNAL_RESPONSE_RECEIPT" />
      </intent-filter>
</receiver>
1 голос
/ 26 июля 2012

Или вы можете сделать одноэлементный класс для регистра:

public class RegisterReceiverSingleton {
private static RegisterReceiverSingleton rrS;
public static final String SENT = "SMS_SENT";
public static final String DELIVERED = "SMS_DELIVERED"; 
private RegisterReceiverSingleton(final Context ctx){
    //when the SMS has been sent
            ctx.registerReceiver(new BroadcastReceiver(){
                    @Override
                    public void onReceive(Context arg0, Intent arg1) {
                        switch (getResultCode())
                        {
                            case Activity.RESULT_OK:
                                Toast.makeText(ctx, "SMS Enviado", 
                                        Toast.LENGTH_SHORT).show();
                                break;
                            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                                Toast.makeText(ctx, "Generic failure", 
                                        Toast.LENGTH_SHORT).show();
                                break;
                            case SmsManager.RESULT_ERROR_NO_SERVICE:
                                Toast.makeText(ctx, "No service", 
                                        Toast.LENGTH_SHORT).show();
                                break;
                            case SmsManager.RESULT_ERROR_NULL_PDU:
                                Toast.makeText(ctx, "Null PDU", 
                                        Toast.LENGTH_SHORT).show();
                                break;
                            case SmsManager.RESULT_ERROR_RADIO_OFF:
                                Toast.makeText(ctx, "Radio off", 
                                        Toast.LENGTH_SHORT).show();
                                break;
                        }
                    }
                }, new IntentFilter(SENT));

            //when the SMS has been delivered
            ctx.registerReceiver(new BroadcastReceiver(){
                @Override
                public void onReceive(Context arg0, Intent arg1) {
                    switch (getResultCode())
                    {
                        case Activity.RESULT_OK:
                            Toast.makeText(ctx, "SMS Entregado", 
                                    Toast.LENGTH_SHORT).show();
                            break;
                        case Activity.RESULT_CANCELED:
                            Toast.makeText(ctx, "SMS No Entregado", 
                                    Toast.LENGTH_SHORT).show();
                            break;                        
                    }
                }
            }, new IntentFilter(DELIVERED));
}

public static RegisterReceiverSingleton getInstance(final Context ctx){
    if(rrS==null){
        rrS = new RegisterReceiverSingleton(ctx);
    }
    return rrS;
}

}

...