You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

短信重复发送:是应用重复请求还是网络问题?

排查短信重复发送问题的思路

嘿,我来帮你捋捋这个重复发短信的问题——你说应用日志里只触发了一次send操作,但客户收到多条,这大概率不是应用层的重复调用,而是Android系统或者SmsManager相关的机制在搞事情。咱们一步步拆解可能的原因和排查方案:

1. 系统自动重试机制在“搞鬼”

Android系统本身有短信发送失败后的自动重试逻辑,比如当短信发送遇到网络波动、无服务等问题时,系统会自动重试发送,但你的自定义日志只记录了应用调用send的次数,没追踪系统层面的重试动作。

排查方案:
完善发送结果的监听逻辑,在PendingIntentSent对应的广播接收器里记录每一次发送结果(包括系统触发的重试):

public class SmsSentReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 把发送结果写入你的SQLite日志,包括结果码和请求标识
        String logContent = String.format("短信发送结果:%d,请求ID:%d", 
            getResultCode(), intent.getIntExtra("sms_request_id", -1));
        // 调用你的日志存储方法
        saveToCustomLog(logContent);

        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:
                // 发送失败,系统可能会自动重试
                break;
        }
    }
}

通过这个日志,你就能清楚看到是不是系统在自动重试发送,而应用层确实只触发了一次send。

2. PendingIntent的FLAG设置或复用问题

如果创建PendingIntentSent/PendingIntentDelivered时没有用唯一的请求码(requestCode),或者FLAG设置不当,可能导致系统误判请求,触发重复发送。尤其是Android 12+之后,对PendingIntent的FLAG有更严格的要求。

修复方案:
每次发送短信时,用唯一的requestCode(比如短信ID、当前时间戳)来创建PendingIntent,同时添加适配Android 12+的FLAG:

// 生成唯一请求码,比如用当前时间戳
int uniqueRequestCode = (int) System.currentTimeMillis();
// 创建发送结果的PendingIntent
PendingIntent sentPI = PendingIntent.getBroadcast(
    this, 
    uniqueRequestCode, 
    new Intent("YOUR_SMS_SENT_ACTION"), 
    PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
// 同理创建送达结果的PendingIntent
PendingIntent deliveredPI = PendingIntent.getBroadcast(
    this, 
    uniqueRequestCode + 1, 
    new Intent("YOUR_SMS_DELIVERED_ACTION"), 
    PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);

3. 长短信被分段发送,被客户误认为“重复”

你的代码里用到了ArrayList<St...,应该是SmsManager.divideMessage()对长短信的分段处理——当短信内容超过单条短信的字符限制(比如ASCII字符70个,Unicode字符160个),SmsManager会自动把内容拆分成多条发送,客户收到的多条连续内容可能被误认为是重复发送。

排查方案:
在send方法里添加分段数量的日志:

private void send(String message, String phoneNumber, PendingIntent pendingIntentSent, PendingIntent pendingIntentDelivered) {
    SmsManager smsManager = getSMSManager();
    ArrayList<String> smsParts = smsManager.divideMessage(message);
    // 记录分段数量到日志
    saveToCustomLog("短信内容过长,被拆分为" + smsParts.size() + "段发送");
    // 后续发送逻辑...
}

如果是这种情况,属于正常的长短信拆分,可以在应用里给用户添加提示,或者告知客户这是正常现象。

4. 运营商侧的异常

极少数情况下,重复发送可能是运营商短信中心的问题——比如短信中心在转发过程中出现异常,导致同一短信被多次下发。

排查方案:
让客户测试发送给不同运营商的号码,看看是不是只有特定运营商出现这个问题;或者尝试更换测试设备的SIM卡,验证是否是特定运营商的问题,必要时联系运营商排查。


内容的提问来源于stack exchange,提问作者Zbarcea Christian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 10:10:53