Android 短信通知的行为

Android 短信通知的行为,android,android-service,android-2.2-froyo,Android,Android Service,Android 2.2 Froyo,rite现在我尝试使用以下代码以编程方式发送SMS,但我不理解SMS发送接收器的行为 1) 例如,如果我发送一条短信,则Activity.RESULT\u OKinside 正在调用registerReceiver三次。如果我用手机发3条短信 通过调用sendSMS然后调用活动进行循环。结果\u OK正在执行 打了9次电话。现在我真的不知道为什么要发一条短信 registerReceiver被调用了这么多次 2) 此外,当我在emulator上运行此代码时,我通过了emulator 端口发送短信

rite现在我尝试使用以下代码以编程方式发送SMS,但我不理解SMS发送接收器的行为

1) 例如,如果我发送一条短信,则
Activity.RESULT\u OK
inside
正在调用registerReceiver
三次。如果我用手机发3条短信 通过调用
sendSMS
然后调用
活动进行循环。结果\u OK
正在执行 打了9次电话。现在我真的不知道为什么要发一条短信 registerReceiver被调用了这么多次

2) 此外,当我在emulator上运行此代码时,我通过了emulator 端口发送短信到其他模拟器,这是自然的,但当我尝试 发送短信到一个真实的号码,然后我没有收到短信传递失败 通知,因为它只通知
活动。结果\u OK

发送短信的代码

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

一般来说,这取决于您发送的邮件的大小-如果邮件超过了单个邮件的限制(在您的情况下,听起来好像是单个邮件限制的3倍),那么您将收到邮件每个部分的发送和传递报告。由于您没有手动拆分消息,因此无法为每个部分指定不同的目的

值得一看的是,您可以自己拆分邮件,然后再进行实际发送。这允许您为消息的不同部分指定不同的挂起意图,以便确定消息最终发送的时间

我认为仿真器将所有消息目的地都视为准确的,因为没有网络返回并说,否则您可能不会从仿真器发送失败(除非您执行类似于将仿真器置于飞行模式的操作)。根据经验,你肯定会在真实的设备上得到这些错误代码

编辑: 考虑到这一点,您每次发送消息时都要注册接收者,我使用的代码有一个清单注册接收者。您可能已经多次注册了它(它的寿命与您注册的上下文一样长),这会给您多次-这也会使它在3条消息中重复9次(假设第三次注册是在第一次发送完成之前完成的)-可能,但我不知道可能性有多大。通过将对象记录在已注册的接收器中,可以进行相对良好的测试

这是我用来发送sms消息的代码的精简版本,它不会得到消息的重复响应:

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);
ArrayList split=smsmsmanager.getDefault().divideMessage(message);
ArrayList success=新建ArrayList(partInfo.length);
意图sendInt=null;
for(int i=0;i
以及我的接收器定义:

<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>

或者您可以为寄存器创建一个单例类:

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

}

我的短信是“John Right,这是我的简单短信!”,所以这条短信没那么长吧?所以仍然需要使用divideMessage?仍然需要(由于HTC的一个bug,它在我的应用程序中很烦人),但它不应该导致对未决意图的三重响应。只是更新了另一种可能性和一些至少对我有效的示例代码!当我再次注册时,你是对的。再次感谢你的快速描述回复。代码示例。这有助于+1too@zeetoobiker您的示例可能会非常有用,只是想知道“partInfo”是什么以及在哪里声明它+1.