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

Android Studio短信重复发送问题:如何实现仅发送一次短信?

短信重复发送&Toast持续显示问题解决

问题分析

从代码来看,重复发送的核心原因是handleMessage方法被多次触发,导致sendSMS反复执行。当前代码里的return只能终止单次handleMessage的执行,但无法阻止后续新的Message进入Handler队列。另外:

  • 当dialog已被dismiss后,代码会执行timer.cancel(),但如果timer没有被彻底停止(比如重复创建timer、cancel后未置空),会持续发送msg.arg1<=0的消息。
  • 没有任何防重复发送的标记,只要handleMessage触发就会调用sendSMS。

解决方案

1. 添加防重复发送标记

在类中添加布尔标记,确保sendSMS仅执行一次:

// 类成员变量
private boolean hasSentEmergencySMS = false;

private void sendSMS(String address, String time){
    // 已发送过则直接返回
    if (hasSentEmergencySMS) return;
    
    SmsManager smsManager = SmsManager.getDefault();
    String name = sharedPreferences.getString("pre_key_name", null);
    String phoneNum = sharedPreferences.getString("pre_key_phone", null);
    String smsContent = time + name + "在" + address + "摔倒!";
    smsManager.sendTextMessage(phoneNum, null, smsContent ,null, null);
    Toast.makeText(context, "消息发送成功", Toast.LENGTH_SHORT).show();
    // 标记为已发送
    hasSentEmergencySMS = true;
}

2. 确保Timer彻底停止

在handleMessage中处理完逻辑后,彻底取消timer并置空,避免后续持续发送消息:

public Handler handler = new Handler(Looper.getMainLooper()){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if(msg.arg1 > 0){
            countingView.setText("                         " + msg.arg1 + context.getApplicationContext().getResources().getString(R.string.fall_contacts));
        }else{
            if(dialog != null){
                dialog.dismiss();
                if(isVibrate){
                    stopVibrate();
                }
                stopAlarm();
                sendSMS(locationAddress, locationTime);
                // 发送后立即彻底停止timer
                if (timer != null) {
                    timer.cancel();
                    timer = null;
                }
                return;
            }
            // 确保timer彻底停止
            if (timer != null) {
                timer.cancel();
                timer = null;
            }
        }
    }
};

3. 补充:重置发送标记(可选)

如果需要在特定场景下重新允许发送(比如用户重置紧急状态),添加重置方法:

public void resetSMSSendFlag() {
    hasSentEmergencySMS = false;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 00:31:01