当前位置: 首页 > 知识库问答 >
问题:

如何检查多部分短信发送是否成功

沈自珍
2023-03-14

我读过很多关于发送短信和多部分短信的帖子,如:

在Android系统中发送短信,在Android系统中发送和接收短信和彩信(pre-Kit Kat Android 4.4),Android系统PendingEvent extras,BroadcastReceiver未接收

... 但他们似乎没有检查消息的所有部分是否成功发送。

据我所知,对于多部分消息,您可以为每个消息部分添加一个PendingEvent,但我看到的示例似乎无法检查所有部分是否成功发送。。。如果是(我猜是第一个),他们似乎认为这是成功的。。。

所以我想我会发送一个多部分的消息,并跟踪各个部分。在成功发送所有部分之前,我不会说消息已成功发送。

我已尝试在以下代码中执行此操作。。。SmsMessageInfo只是一个简单的类,包含电话号码、一条消息、已处理部件的布尔值列表和已成功发送部件的列表,它还有一个唯一的消息Id。

我尝试了以下方法:

private void sendLongSmsMessage(Context context, final SmsMessageInfo messageInfo) {

    // Receive when each part of the SMS has been sent (or does it????)
    context.registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String messageIdAsString = intent.getExtras().getString(INTENT_EXTRA_MESSAGE_ID_KEY);

            Log.i("SMSMessageSender", "Broadcast Intent Recieved, IntentMessageID: " + messageIdAsString + "  messageInfoId: " + messageInfo.messageId);

            if (messageIdAsString != null) {
                if (Long.parseLong(messageIdAsString) == messageInfo.messageId) {
                    String messagePartNrAsString = (String) intent.getExtras().get(INTENT_EXTRA_PART_NR_KEY);
                    int messagePartNr = Integer.parseInt(messagePartNrAsString);

                    Log.i("SMSMessageSender", "Broadcast Intent Recieved Multi Part Message Part No: " + messagePartNrAsString);

                    // We need to make all the parts succeed before we say we have succeeded.
                    switch (getResultCode()) {
                    case Activity.RESULT_OK:
                        messageInfo.partsSent.add(messagePartNr, true);
                        break;
                    case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                        messageInfo.failMessage = "Error - Generic failure";
                        break;
                    case SmsManager.RESULT_ERROR_NO_SERVICE:
                        messageInfo.failMessage = "Error - No Service";
                        break;
                    case SmsManager.RESULT_ERROR_NULL_PDU:
                        messageInfo.failMessage = "Error - Null PDU";
                        break;
                    case SmsManager.RESULT_ERROR_RADIO_OFF:
                        messageInfo.failMessage = "Error - Radio off";
                        break;
                    }

                    messageInfo.partsProcessed.add(messagePartNr, true);

                    boolean allSent = true;
                    for (Boolean partSent : messageInfo.partsSent) {
                        allSent = allSent && partSent;
                    }
                    messageInfo.sent = allSent;

                    boolean allProcessed = true;
                    for (Boolean partProcessed : messageInfo.partsProcessed) {
                        allProcessed = allProcessed && partProcessed;
                    }

                    if (allProcessed) {
                        // We have our response for all of our message parts, so we can unregister our receiver.
                        Log.i("SMSMessageSender", "All message part resoponses received, unregistering message Id: " + messageIdAsString);
                        context.unregisterReceiver(this);
                    } 
                } else {
                    Log.w("SMSMessageSender", "Received a broadcast message with Id for a different message");
                }
            } else {
                Log.w("SMSMessageSender", "Received a broadcast message but not for message Id");
            }
        }
    }, new IntentFilter(SENT));

    ArrayList<String> messageList = SmsManager.getDefault().divideMessage(messageInfo.message);
    ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>(messageList.size());

    messageInfo.partsSent.clear();

    for (int i = 0; i < messageList.size(); i++) {
        messageInfo.partsSent.add(i, false);
        messageInfo.partsProcessed.add(i, false);

        Intent sentIntent = new Intent(SENT);
        sentIntent.putExtra(INTENT_EXTRA_MESSAGE_ID_KEY, Long.toString(messageInfo.messageId));
        sentIntent.putExtra(INTENT_EXTRA_PART_NR_KEY, Integer.toString(i));

        Log.i("SMSMessageSender", "Adding part " + i + " tp multi-part message Id: " + messageInfo.messageId);
        pendingIntents.add(PendingIntent.getBroadcast(context, 0, sentIntent,  PendingIntent.FLAG_ONE_SHOT));
    }

    Log.i("SMSMessageSender", "About to send multi-part message Id: " + messageInfo.messageId);
    SmsManager.getDefault().sendMultipartTextMessage(messageInfo.phoneNumber, null, messageList, pendingIntents, null);
}

这样做的问题是第二个消息部分永远不会被接收。

这似乎很奇怪,必须要经历创建多个悬挂式帐篷的所有麻烦,却不去检查它们是否都有效。

在我显示消息部分No的日志消息中,它始终为0,我从未获得第二部分,因此此代码从未认为它已完成。

我是不是把它弄得太复杂了,我是不是应该把任何旧的Pending帐篷拿回来,然后假设其他的也一样(在这种情况下,谷歌为什么要让你首先提供它们的列表)。

我为这个冗长的问题道歉,但我真的不知道如何用更短的方式问得更清楚:-)

问候科林

共有2个答案

卜季萌
2023-03-14

我正在使用下面的代码将多部分消息发送给多个联系人,效果很好:

    // Send the SMS message
    SmsManager sms = SmsManager.getDefault();
    ArrayList<String> parts = sms.divideMessage(content);
        final int numParts = parts.size();

    ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();
    sentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            Log.d(TAG, "SMS onReceive intent received.");
            boolean anyError = false;
            switch (getResultCode()) {
            case Activity.RESULT_OK:
                break;
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
            case SmsManager.RESULT_ERROR_NO_SERVICE:
            case SmsManager.RESULT_ERROR_NULL_PDU:
            case SmsManager.RESULT_ERROR_RADIO_OFF:
                anyError = true;
                break;
            }
            msgParts--;
            if (msgParts == 0) {
                hideProgressBar();
                if (anyError) {
                    Toast.makeText(context,
                            getString(R.string.sms_send_fail),
                            Toast.LENGTH_SHORT).show();
                } else {
                    //success

                }

                unregisterReceiver(sentReceiver);
            }

        }
    };
    registerReceiver(sentReceiver, new IntentFilter(SENT_ACTION));

    // SMS delivered receiver
    // registerReceiver(new BroadcastReceiver() {
    // @Override
    // public void onReceive(Context context, Intent intent) {
    // Log.d(TAG, "SMS delivered intent received.");
    // }
    // }, new IntentFilter(DELIVERED_ACTION));

    for (int i = 0; i < numParts; i++) {
        sentIntents.add(PendingIntent.getBroadcast(this, 0, new Intent(
                SENT_ACTION), 0));
    }

    for (PhoneInfo phone : recipientsList) {
        sms.sendMultipartTextMessage(phone.num, null, parts, sentIntents,
                null);
    }
    msgParts = numParts * recipientsList.size();
    showProgressBar();
洪弘毅
2023-03-14

以下是我最终使用的代码,它是我的原创代码和博尔顿的代码的混合(感谢博尔顿:-)。

新代码可以更好地检测部分的故障,这有点难测试,上面的代码将每个消息部分的anyError设置为false,所以如果第1部分失败,第2部分成功,它可能会认为整个过程成功了。。。下面的代码调用(我的)messageInfo。失败,如果后续消息部分成功,则不会重置。。。我想这是完全不必要的,因为你会认为,如果一个部分起作用,其他部分也会起作用。。。不管怎样,下面是我最终使用的代码。

编辑

谢谢。

private void sendLongSmsMessage4(Context context, final SmsMessageInfo messageInfo) {

    // Receive when each part of the SMS has been sent
    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // We need to make all the parts succeed before we say we have succeeded.
            switch (getResultCode()) {
            case Activity.RESULT_OK:
                break;
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                messageInfo.fail("Error - Generic failure");
                break;
            case SmsManager.RESULT_ERROR_NO_SERVICE:
                messageInfo.fail("Error - No Service");
                break;
            case SmsManager.RESULT_ERROR_NULL_PDU:
                messageInfo.fail("Error - Null PDU");
                break;
            case SmsManager.RESULT_ERROR_RADIO_OFF:
                messageInfo.fail("Error - Radio off");
                break;
            }

            nMsgParts--;
            if (nMsgParts <= 0) {
                // Stop us from getting any other broadcasts (may be for other messages)
                Log.i(LOG_TAG, "All message part resoponses received, unregistering message Id: " + messageInfo.getMessageId());
                context.unregisterReceiver(this);

                if (messageInfo.isFailed()) {
                    Log.d(LOG_TAG, "SMS Failure for message id: " + messageInfo.getMessageId());
                } else {
                    Log.d(LOG_TAG, "SMS Success for message id: " + messageInfo.getMessageId());
                    messageInfo.setSent(true);
                }
            }
        }
    };

    context.registerReceiver(broadcastReceiver, new IntentFilter(SENT + messageInfo.getMessageId()));

    SmsManager smsManager = SmsManager.getDefault();

    ArrayList<String> messageParts = smsManager.divideMessage(messageInfo.getMessage());
    ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>(messageParts.size());
    nMsgParts = messageParts.size();

    for (int i = 0; i < messageParts.size(); i++) {
        Intent sentIntent = new Intent(SENT + messageInfo.getMessageId());
        pendingIntents.add(PendingIntent.getBroadcast(context, 0, sentIntent, 0));
    }

    Log.i(LOG_TAG, "About to send multi-part message Id: " + messageInfo.getMessageId());
    smsManager.sendMultipartTextMessage(messageInfo.getPhoneNumber(), null, messageParts, pendingIntents, null);
}
 类似资料:
  • 我提供以下代码,以便发送多部分短信,并检查是否送达,以回复发送方: ExecuteCommand是接收传入短信并最终回复发送方一条短信的BroadCastReciver 和类proivde用于发送意图,以确定发送和传递的状态为: } 最后短信正确接收但发送回复短信我认为这是由发送收件人动态寄存器接收引起的

  • 问题内容: 我正在尝试从我的应用程序发送紧急短信。我必须确保SMS发送成功。 在Android系统启动后并进行检查后,将发送SMS。 因此,我有一个处理BOOT_COMPLETED意向过滤器的服务类。此类进行检查,如果内容正确,则尝试通过另一个“扩展服务”类发送SMS消息 确保成功发送短信后,两个服务(处理启动呼叫的服务和发送短信的服务)都必须退出。 问题1 :如何使我的短信发送功能在超时的情况下

  • 问题内容: 我正在写一个可以设置标题的库。如果标题已经发送,我想给出一个自定义错误消息,而不是让它失败并显示Node.js给出的“发送后无法设置标题”消息。那么如何检查标头是否已经发送? 问题答案: 编辑:从Express 4.x开始,您需要使用res.headersSent。 还要注意,您可能要在检查之前使用setTimeout,因为在调用res.send()之后,它不会立即设置为true。资源

  • 问题内容: 从Java应用程序发送和接收短信的可能方法是什么? 问题答案: 如果您想要的只是简单的通知,许多运营商都支持通过电子邮件发送短信;通过电子邮件查看短信

  • 我有一个windows应用程序发送短信连接到GSM调制解调器。我只使用AT命令连接到端口和发送文本。 下面是ExecCommand方法

  • 问题内容: 好吧,我是SQL的新手,我刚刚读到,存储过程始终返回一个值,确定该过程中的查询是否已成功执行是一种很好的做法。 所以我有一个带有select语句的简单存储过程,如果要执行,我想返回1,否则返回-1。 您能告诉我如何用SQL编写该条件吗? 如果有关系,我的数据库是MS SQL Server。 谢谢你。 问题答案: 使用输出参数返回成功状态以及Try..Catch块