SMS通知的行为

Hun*_*unt 2 android android-service android-2.2-froyo

现在我试图使用以下代码以编程方式发送短信,但我不明白SMS SENT接收器的行为.

1)例如,如果我发送一条短信,那么Activity.RESULT_OK 内部 registerReceiver被叫3次.如果我用3发短信loopby调用sendSMSActivity.RESULT_OK是被称为9倍.现在我真的不知道一个短信发送为什么这个registerReceiver被调用了这么多次?

2)此外,当我在模拟器中运行这段代码我通过仿真端口发送短信到其他仿真这是自然的,但是当我尝试发送短信为实数,然后我没有得到短信发送失败通知,因为它会通知Activity.RESULT_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);               
        } 
Run Code Online (Sandbox Code Playgroud)

zee*_*ker 6

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

值得一看的是SmsManager.divideMessage()自己拆分消息,然后在SmsManager.sendMultiPartTextMessage()中进行实际发送.这允许您为消息的不同部分指定不同的待处理意图,以便您可以确定消息最终发送的时间.

我认为模拟器正在将所有消息目的地视为准确,因为没有网络可以回来说,否则你可能不会从模拟器发送失败(除非你做了像模拟器在飞行模式下做的事情).根据经验,您肯定会在真实设备上获取这些错误代码.

编辑: 考虑到它,你每次发送消息时都会注册接收器,我使用的代码有一个明显的注册接收器.您有可能多次注册它(只要您注册的上下文存在),这会多次给您 - 这也可能使它重复3次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);
Run Code Online (Sandbox Code Playgroud)

我的接收器定义:

<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>
Run Code Online (Sandbox Code Playgroud)