首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >短信通知的行为

短信通知的行为
EN

Stack Overflow用户
提问于 2012-03-13 07:35:32
回答 2查看 1.9K关注 0票数 2

现在我试着用下面的代码编程发送SMS,但是我不理解SMS发送接收器的行为。

1)例如,如果我发送一条短信,那么Activity.RESULT_OK内部的registerReceiver就会被调用3次。如果我发送3条短信通过调用sendSMS进行循环,那么Activity.RESULT_OK将被调用9次。现在我真的不知道一个短信发送为什么这个registerReceiver被调用了这么多次? 2)此外,当我在模拟器上运行此代码时,我通过模拟器端口将SMS发送到其他仿真程序,这是很自然的,但当我试图将SMS发送到实数时,我不会收到SMS发送失败通知,因为它只通知Activity.RESULT_OK

发送短消息的代码

代码语言:javascript
复制
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);               
        } 
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-13 08:04:31

一般来说,这取决于您要发送的消息的大小--如果消息超过了单个消息的限制(在您的例子中,它听起来大约是单个消息限制的3倍),那么您将得到消息的每个部分的发送和传递报告。因为您没有手动拆分消息,所以不能为每个部分指定不同的意图。

值得一看的是SmsManager.divideMessage()自己拆分消息,然后在SmsManager.sendMultiPartTextMessage()进行实际发送。这允许您为消息的不同部分指定不同的挂起意图,这样您就可以确定消息何时最后发送了。

我认为仿真器将所有消息目的地视为准确,而且由于没有网络返回,否则您很可能不会从模拟器发送失败(除非您做了类似于将模拟器置于飞机模式)。根据经验,您确实可以在真正的设备上获得这些错误代码。

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

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

代码语言:javascript
复制
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);

我的受话人定义:

代码语言:javascript
复制
<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>
票数 6
EN

Stack Overflow用户

发布于 2012-07-25 23:02:17

或者您可以为注册表做一个单例类:

代码语言:javascript
复制
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;
}

}

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9680004

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档