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

短信发送:系统显示短信发送成功,但实际上没有

堵宪
2023-03-14

我的应用程序通过SmsManager.sendMultipartTextMessage发送短信,然后通知服务器短信发送的状态。

一切正常,但Yota操作员有问题。短信不会发送到 MTS 运营商的手机。Yota运营商的员工声称MTS运营商阻止接收来自Yota的消息。

这不是我们的问题,但Android系统说,这样的短信成功交付。我们无法从其他手机重新发送此类短信,因为我们的系统认为它们已经成功发送。

如果应用程序尝试发送此类短信,系统首先发出短信发送成功的信号,然后发送短信成功。听起来不错,但实际上短信没有送达。这不是一个孤立的案例。在不同的设备上进行了测试。还尝试通过MTS运营商将短信发送到不同的手机。

我试图通过标准的“消息”应用程序发送相同的短信,并注意到以下几点:

从我的应用程序发送的短信在不同设备上的标准“消息”应用程序中显示不同。例如,中兴BLADE L110(API 22)显示错误发送消息,而小米Redmi 3S(API 23)没有。但在两部智能手机上,当我尝试通过标准应用程序发送此类短信时,会显示错误发送消息(中兴通讯在此之前显示Toast“短信已成功发送”)。

谁能帮忙?有没有其他方法可以检查短信是否已发送?当系统生成带有消息已成功发送和传递的信号的意图时,标准的“消息”应用程序如何记录短信发送错误的事实?

这是我的代码:

发送短信工作:

public class SendSMSJob extends SimpleJobService {

    public static final String EXTRA_SMS_LIST_JSON = "sms_list";
    public static final String TAG = "send_sms_job";

    private static final String ACTION_SENT = "ru.sp2all.smsgate.SMS_SENT";
    private static final String ACTION_DELIVERED = "ru.sp2all.smsgate.SMS_DELIVERED";

    private int startId;

    @Override
    public void onCreate() {
        super.onCreate();
        MyLog.i(getLogTag(), "onCreate()");
    }

    @Override
    public int onRunJob(JobParameters parameters) {
        try {
            this.startId = startId;
            String json = parameters.getExtras().getString(EXTRA_SMS_LIST_JSON);
            Gson gson = new Gson();
            SMSDataList smsDataList = gson.fromJson(json, SMSDataList.class);

            MyLog.d(getLogTag(), "Sending " + String.valueOf(smsDataList.items.length) + " messages");

            boolean complete = true;
            boolean needRetry = true;
            for (SMSData sms: smsDataList.items) {
                Integer subscriptionId = SimsHelper.getSimSubscriptionIdForIndex(getApplicationContext(), sms.simIndex);
                SmsManager smsManager = null;
                if (subscriptionId != null) {
                    smsManager = SmsManager.getSmsManagerForSubscriptionId(subscriptionId);
                } else {
                    smsManager = SmsManager.getDefault();
                }
                ArrayList<String> parts = smsManager.divideMessage(sms.message);
                MyLog.i(getLogTag(), "parts.size=" + parts.size());

                insertSmsToDB(sms, parts);

                ArrayList<PendingIntent> deliveryIntents = new ArrayList<>(parts.size());
                ArrayList<PendingIntent> sentIntents = new ArrayList<>(parts.size());

                try {
                    for (int part = 0; part < parts.size(); part++) {
                        Intent sentIntent = new Intent(ACTION_SENT);

                        sentIntent.putExtra("id",     sms.smsId + "_" + Integer.toString(part));
                        sentIntent.putExtra("sms_id", sms.smsId);
                        sentIntent.putExtra("parts",  Integer.toString(parts.size()));
                        sentIntent.putExtra("part", Integer.toString(part));
                        sentIntent.putExtra("phone", sms.phone);
                        sentIntent.putExtra("msg", sms.message);

                        PendingIntent sentPI = PendingIntent.getBroadcast(this,
                                Integer.parseInt(sms.smsId) * 100 + part,
                                sentIntent,
                                PendingIntent.FLAG_UPDATE_CURRENT);
                        sentIntents.add(sentPI);

                        Intent deliveredIntent = new Intent(ACTION_DELIVERED);

                        deliveredIntent.putExtra("id",     sms.smsId + "_" + Integer.toString(part));
                        deliveredIntent.putExtra("sms_id", sms.smsId);
                        deliveredIntent.putExtra("parts",  Integer.toString(parts.size()));
                        deliveredIntent.putExtra("part",   Integer.toString(part));
                        deliveredIntent.putExtra("phone", sms.phone);
                        deliveredIntent.putExtra("msg", sms.message);

                        PendingIntent deliveredPI = PendingIntent.getBroadcast(this,
                                Integer.parseInt(sms.smsId) * 100 + part,
                                deliveredIntent,
                                PendingIntent.FLAG_UPDATE_CURRENT);
                        deliveryIntents.add(deliveredPI);
                    }

                    MyLog.i(getLogTag(), "Sending to " + sms.phone);
                    smsManager.sendMultipartTextMessage(sms.phone, null, parts,
                            sentIntents, deliveryIntents);

                } catch (Exception e) {
                    ErrorReporter.exception(this, getLogTag(), e, new ErrorReporter.ReporterHandler(e));
                    complete = true;
                }
            }
            if (complete) {
                return RESULT_SUCCESS;
            } else if (needRetry) {
                return RESULT_FAIL_RETRY;
            } else {
                return RESULT_FAIL_NORETRY;
            }
        } catch (Exception e) {
            ErrorReporter.exception(this, getLogTag(), e, new ErrorReporter.ReporterHandler(e));
            return RESULT_FAIL_RETRY;
        }
    }

    private String getLogTag() {
        return getClass().getSimpleName();
    }
}

已在AndroidManifest广播接收器中注册,用于SMS状态处理:

    <receiver android:name=".SMSSentReceiver">
        <intent-filter>
            <action android:name="ru.sp2all.smsgate.SMS_SENT" />
        </intent-filter>
    </receiver>

    <receiver android:name=".SMSDeliveredReceiver">
        <intent-filter>
            <action android:name="ru.sp2all.smsgate.SMS_DELIVERED" />
        </intent-filter>
    </receiver>

SMS发送的广播接收器:

public class SMSSentReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            String sms_id = intent.getStringExtra("sms_id");
            int part = Integer.parseInt(intent.getStringExtra("part"));
            MyLog.d(getLogTag(), "br_sent " + sms_id);

            int status = 0;

            int code = getResultCode();

            switch (code) {
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    status = 400;
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    status = 401;
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    status = 402;
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    status = 403;
                    break;
                case Activity.RESULT_OK:
                    updateDBWithNewSentPartsCount();
                    status = 202; // 202 is SMS sent Server status
                    break;
                default:
                    status = 404; break;
            }

            if (status == 202) {
                int sent = getSentPartsFromDB();
                int parts = getAllPartsFromDB();
                MyLog.d(getLogTag(), "DB sent:" + sms_id + " - : sent:" + sent + " parts: " + parts);
                if (sent >= parts) {
                    MyLog.d(getLogTag(), "DB sent all parts");
                    Network.sendSMSStatus(context, sms_id, status);
                }
            } else {
                Network.sendSMSStatus(context, sms_id, status);
            }

        } catch (Exception e) {
            ErrorReporter.exception(context, getLogTag(), e, new ErrorReporter.ReporterHandler(e));
        }
    }

    private String getLogTag() {
        return getClass().getSimpleName();
    }

}

短信发送的广播接收器:

public class SMSDeliveredReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            String sms_id = intent.getStringExtra("sms_id");
            int part = Integer.parseInt(intent.getStringExtra("part"));
            MyLog.d(getLogTag(), "br_delivered " + sms_id);
            int resultCode = getResultCode();

            switch (resultCode) {
                case Activity.RESULT_OK:

                    updateDBWithNewDeliveredPartsCount();

                    int delivered = getDeliveredPartsFromDB();
                    int parts = getAllPartsFromDB();
                    MyLog.i(getLogTag(), "DB delivered: " + sms_id + ", " + delivered + " parts of " + parts);
                    if (delivered >= parts) {
                        MyLog.i(getLogTag(), "DB delivered all parts");
                        Network.sendSMSStatus(context, sms_id, 200); // 200 is SMS delivered Server status
                    }

                    break;
                case Activity.RESULT_CANCELED:
                    MyLog.w(getLogTag(), "DB delivered: CANCELLED " + sms_id);
                    Network.sendSMSStatus(context, sms_id, 405);
                    break;
                default:
                    MyLog.w(getLogTag(), "DB delivered: unknown code " + resultCode);
                    Network.sendSMSStatus(context, sms_id, resultCode);
            }
        } catch (Exception e) {
            ErrorReporter.exception(context, getLogTag(), e, new ErrorReporter.ReporterHandler(e));
        }
    }

    private String getLogTag() {
        return getClass().getSimpleName();
    }
}

当我尝试发送短信和短信实际上没有发送时,从设备登录:

SendSMSJob: onCreate()
SendSMSJob: Sending 1 messages
SendSMSJob: parts.size=1
SendSMSJob: Sending to +7988*******
SMSSentReceiver: br_sent 704402
SMSSentReceiver: DB sent:704402 - : sent:1 parts: 1
SMSSentReceiver: DB sent all parts
Network: sendSMSStatus status: 202
Network: get: https://{SERVER_NAME}/result.php?status=202&smsId=704402
Network: got: {"status":200}
SMSDeliveredReceiver: br_delivered 704402
SMSDeliveredReceiver: DB delivered: 704402, 1 parts of 1
SMSDeliveredReceiver: DB delivered all parts
Network: sendSMSStatus status: 200
Network: get: https://{SERVER_NAME}/result.php?status=200&smsId=704402
Network: got: {"status":200}

测试短信文本:gate4

共有1个答案

龙洛城
2023-03-14

SMS不是公认的协议。你无法知道是否已经从发送端送达。发送者只能知道消息何时被发送。发送报告正确,因为数据正在发送,但它在另一端被阻止。

如果您需要确认的SMS,您可以从接收者那里回复,但这将涉及开发您自己的确认协议。

我只是从设备中轮询一个web服务。无论如何,数据比短信便宜很多。

祝你好运

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

  • 本文向大家介绍Twilio 发送短信,包括了Twilio 发送短信的使用技巧和注意事项,需要的朋友参考一下 示例 要使用Twilio和Python发送您的第一条SMS,您只需要Twilio-Python帮助程序库即可开始。            

  • egg 发送短信逻辑 service 'use strict'; const Service = require('egg').Service; class UserService extends Service { /** * 发送验证码 */ async sendCode() { //1. 获取用户手机号 const { phone } = this

  • 我一直在与Twilio合作,向一个应用程序的潜在用户发送短信。我已经想出了如何向美国号码发送信息,但向国际移动用户发送短信就更棘手了。我来这里是想看看是否有人能帮我找出我做错了什么,并听听任何解决问题的建议。我已经建立了一个简单的网页,其中有一个国际代码的下拉菜单,以及移动号码的输入表单和一个将信息发送到Twilio服务器的按钮。其代码如下所示: 另一个PHP(textmelink.PHP)文件处

  • 本文向大家介绍php实现短信发送代码,包括了php实现短信发送代码的使用技巧和注意事项,需要的朋友参考一下 卓望的短信发送。PHP格式。都要不习惯用xml传输数据格式了 标签: <无> 1. [代码][PHP]代码     以上所述就是本文的全部内容了,希望大家能够喜欢。

  • 我试图自动发送短信到某一个号码时,用户按下屏幕上的一个按钮。