4

我们在 Android 上使用 SMSManager 从设备向其他人发送短信。

我们有报告称,用户没有收到我们认为已发送的 SMS,这是基于使用 Activity.RESULT_OK 调用了 sentIntent 的事实——但这似乎发生在本地 SMS 服务只是将消息排队等待发送而不一定要发送时当它真正发送时。

所以我认为我们应该使用deliveryIntent。

这里的问题是我总是得到 sentIntent 回调,但从来没有得到 deliveryIntent 回调。

有任何想法吗?代码如下,谢谢。

        // The intent action to be unique so that we can have multiple
        // concurrent  pending intents.
        // http://developer.android.com/reference/android/app/PendingIntent.html
        String intentAction = TAG + "-" + callbackId;  // callbackId is unique
        Intent intent = new Intent(intentAction);
        intent.putExtra("phoneNumber", phoneNumber);
        intent.putExtra("callbackId", callbackId);
        intent.putExtra("message", message);

        PendingIntent sentPI = PendingIntent.getBroadcast(
            cordova.getActivity(), 0, intent, 0);

        cordova.getActivity().registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context ctx, Intent intent) {
                String sentToPhoneNumber = intent.getStringExtra("phoneNumber");
                String callbackId = intent.getStringExtra("callbackId");
                String message = intent.getStringExtra("message");
                int resultCode = getResultCode();
                int status = -1;
                String details = "";
                logger.log(Level.INFO, TAG + " SENT intent!! to: " +
                           sentToPhoneNumber + ", resultCode: " + resultCode);
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        status = 0;
                        break;
                    case SmsManager.RESULT_ERROR_NO_SERVICE:
                        details = "No service";
                    case SmsManager.RESULT_ERROR_NULL_PDU:
                        details = "Null PDU";
                    case SmsManager.RESULT_ERROR_RADIO_OFF:
                        details = "Radio off";
                        status = 1;
                        break;
                }

                JSONObject obj = new JSONObject();
                try {
                    obj.put("status", status);
                    obj.put("details", details);
                    obj.put("phone_number", sentToPhoneNumber);
                    obj.put("message", message);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
                sendAsyncResultStatus(callbackId, obj);
                ctx.unregisterReceiver(this);
            }
        }, new IntentFilter(intentAction));

        // The intent action to be unique so that we can have multiple
        // concurrent  pending intents.
        // http://developer.android.com/reference/android/app/PendingIntent.html
        String deliveryIntentAction = TAG + "-Delivery-" + callbackId;
        Intent deliveryIntent = new Intent(deliveryIntentAction);
        deliveryIntent.putExtra("phoneNumber", phoneNumber);
        deliveryIntent.putExtra("callbackId", callbackId);
        deliveryIntent.putExtra("message", message);

        PendingIntent deliveryPI = PendingIntent.getBroadcast(
            cordova.getActivity(), 0, deliveryIntent, 0);

        cordova.getActivity().registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context ctx, Intent intent) {
                logger.log(Level.INFO, TAG + " DELIVERY intent YOYO!!");
                String sentToPhoneNumber = intent.getStringExtra("phoneNumber");
                String callbackId = intent.getStringExtra("callbackId");
                String message = intent.getStringExtra("message");
                String pdu = intent.getStringExtra("pdu");
                logger.log(Level.INFO, TAG + " DELIVERY intent!! to: " +
                        sentToPhoneNumber + ", pdu: " + pdu);

                JSONObject obj = new JSONObject();
                try {
                    obj.put("pdu", pdu);
                    obj.put("phone_number", sentToPhoneNumber);
                    obj.put("message", message);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
                sendAsyncResultStatus(callbackId, obj);
                ctx.unregisterReceiver(this);
            }
        }, new IntentFilter(deliveryIntentAction));

        smsManager.sendTextMessage(phoneNumber, null, message, sentPI, deliveryPI);
4

2 回答 2

5

DeliveryIntent 依赖于某些运营商提供的 DeliveryReports。

有些运营商确实提供 DeliveryReports,有些则不提供。运营商对 DliveryReports 的支持分为三类...

  • 提供商根本不提供 DeliveryReport。
  • 提供商总是提供虚假的 DeliveryReport(即使是无效号码,您也会得到 OK 报告)
  • 提供商确实提供了交付报告。

复杂性并不止于此...如果您的提供商(发送提供商)确实支持交付报告,那么您将主要在向同一运营商的订阅者发送消息时获得交付报告。但是,当您在该运营商之外发送消息时,您可能会或可能不会收到递送报告。在大多数情况下,您不会。

这可能是由多种原因引起的,例如

  • 目的地提供商不支持送达报告
  • 一些中间 SMS 网关不支持发送报告
  • 目的地运营商或某些中间网关的 DeliveryReports 与始发运营商的不兼容。

到目前为止,在这种情况下的交付报告并不是我所知道的有保证的信息。

于 2014-02-12T21:19:17.680 回答
0

我可以想象交付意图取决于退货收据的接收。网络提供商需要发送这些信息才能使您的程序正常运行。

您可以通过打开“设置菜单”,浏览到“短信设置”并勾选“回执”框来完成此操作。

于 2013-09-05T13:00:29.247 回答