6

次のような SMS およびマルチパート SMS メッセージの送信に関する多くの投稿を読みました。

Android でのSMS の送信、Androidでの SMS および MMS の送受信 (Kit Kat Android 4.4 より前)Android PendingIntent エクストラ、BroadcastReceiver で受信されない

...などですが、メッセージのすべての部分が正常に送信されたことを確認していないようです。

私が理解していることから、マルチパートメッセージでは、メッセージの各部分に PendingIntent を追加しますが、私が見た例では、すべての部分が正常に送信されたことを確認していないようです... ) 彼らはそれが成功したと思っているようです...

そこで、マルチパート メッセージを送信して、その部分を追跡しようと考えました。すべての部分が正常に送信されるまで、メッセージが正常に送信されたとは言えません。

次のコードでこれを実行しようとしました... 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);
}

これの問題は、2 番目のメッセージ部分がまったく受信されないことです。

複数の PendingIntents を作成するという面倒な作業をすべて行って、それらがすべて機能していることを確認しないのは奇妙に思えます。

Message Part No を表示するログ メッセージでは、常に 0 です。2 番目の部分を取得しないため、このコードは完了したとは考えません。

複雑にしすぎているのでしょうか。古い PendingIntent が戻ってきて、残りの部分にも同じことが当てはまると想定する必要があります (その場合、なぜ Google は最初にそれらのリストを提供するようにしたのですか)。

長い質問で申し訳ありませんが、短い方法でより明確に質問する方法が本当にわかりませんでした:-)

よろしくコリン

4

2 に答える 2

7

これが私が最終的に使用したコードです。これは私のオリジナルとボルトンのコードを組み合わせたものです(ボルトンに感謝します:-))。

新しいコードは、部分の失敗をより適切に検出する可能性がありますが、テストが少し難しくなります。上記のコードは、メッセージ部分ごとに anyError を false に設定するため、部分 1 が失敗し、部分 2 が成功した場合、すべてが成功したと見なされる可能性があります...以下のコードは、(my) messageInfo.fail を呼び出します。これは、後続のメッセージ部分が成功した場合にリセットされません...一部が機能する場合、残りも機能すると思うので、これはすべてかなり不要だと思います... とにかく、以下は私が最終的に使用したコードです。

編集>負荷が高い場合、複数のインテント(私が思うに)が1つにマージされたため、インテント内のエクストラを削除するようにコードを更新しました(異なるPendingIntentフラグを使用しても役に立ちませんでした)。最後に、メッセージごとに異なるインテント アクションを使用しました (例: new Intent(SENT + messageInfo.getMessageId()))。これにより、レシーバーは確実に自身のメッセージのブロードキャストのみを取得します。重い負荷の下でよりよく動作するようです。

ありがとう。

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);
}
于 2013-05-21T01:54:21.910 に答える
0

以下のコードを使用してマルチパート メッセージを複数の連絡先に送信しましたが、正常に動作します。

    // 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();
于 2013-05-20T06:22:23.203 に答える