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

Android点击Active/Deactive按钮后TextView无法正常更新问题求助

解决短信发送与TextView状态更新异常问题

我帮你梳理下代码里的几个关键问题,以及对应的修复方案:

核心问题分析

  1. Switch语句缺少break:你的onClick方法中,case R.id.button2执行完后没有加break,导致代码会继续执行case R.id.button4的逻辑——也就是说,不管你点击哪个按钮,最终都会调用sendNackMsg把TextView设为“disable”,这就是状态一直不变的根本原因。

  2. 重复调用setContentView:在sendMsg方法里你又执行了setContentView(R.layout.activity_main),这会重新加载整个布局,导致你之前初始化的控件引用全部失效,后续的setText其实是给新创建的TextView设置的,界面上显示的还是旧的控件,所以看不到状态变化。

  3. 硬编码短信参数:sendMsg里调用smsManager.sendTextMessage时用了硬编码的号码和内容,没有使用传入的thenumber和mymsg,导致点击按钮发送的内容不符合预期。

  4. TextView初始化时机错误:你每次发送短信时才去findViewById,加上重复加载布局,根本找不到界面上正在显示的那个TextView。

修复后的代码

1. 全局变量与初始化优化

首先在Activity中声明全局TextView变量,在onCreate中一次性初始化:

private TextView textStatus;
private IntentFilter intentFilter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    // 初始化TextView,后续直接复用这个引用
    textStatus = findViewById(R.id.Textstatus);
    
    intentFilter = new IntentFilter();
    intentFilter.addAction("SMS_RECEIVED_ACTION");
    
    Button activeBtn = findViewById(R.id.button2);
    activeBtn.setOnClickListener(this);
    Button deactiveBtn = findViewById(R.id.button4);
    deactiveBtn.setOnClickListener(this);
}

2. 修正onClick的Switch逻辑

给每个case加上break,避免代码串执行:

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.button2:
            String activateMsg = "CMDSAD_ON";
            String targetNumber = "916722";
            sendMsg(targetNumber, activateMsg);
            break; // 必须加break,终止当前case的执行
        case R.id.button4:
            String deactivateMsg = "CMDSAD_OFF";
            String targetNum = "916722";
            sendNackMsg(targetNum, deactivateMsg);
            break; // 同样加break
        default:
            break;
    }
}

3. 修复sendMsg方法

去掉重复的setContentView,使用全局TextView,并改用传入的参数发送短信:

public void sendMsg(String thenumber, String mymsg){
    String SENT = "Message sent";
    String DELIVERED = "Message delivered";
    SmsManager smsManager = SmsManager.getDefault();
    Context curContext = this.getApplicationContext();
    
    PendingIntent sentPending = PendingIntent.getBroadcast(curContext, 0, new Intent(SENT), 0);
    curContext.registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context arg0, Intent arg1) {
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "Sent.", Toast.LENGTH_LONG).show();
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    Toast.makeText(getBaseContext(), "Not Sent: Generic failure.", Toast.LENGTH_LONG).show();
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    Toast.makeText(getBaseContext(), "Not Sent: No service (possibly, no SIM-card).", Toast.LENGTH_LONG).show();
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    Toast.makeText(getBaseContext(), "Not Sent: Null PDU.", Toast.LENGTH_LONG).show();
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    Toast.makeText(getBaseContext(), "Not Sent: Radio off (possibly, Airplane mode enabled in Settings).", Toast.LENGTH_LONG).show();
                    break;
            }
        }
    }, new IntentFilter(SENT));
    
    PendingIntent deliveredPending = PendingIntent.getBroadcast(curContext, 0, new Intent(DELIVERED), 0);
    curContext.registerReceiver(
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context arg0, Intent arg1) {
                switch (getResultCode()) {
                    case Activity.RESULT_OK:
                        Toast.makeText(getBaseContext(), "Delivered.", Toast.LENGTH_LONG).show();
                        break;
                    case Activity.RESULT_CANCELED:
                        Toast.makeText(getBaseContext(), "Not Delivered: Canceled.", Toast.LENGTH_LONG).show();
                        break;
                }
            }
        }, new IntentFilter(DELIVERED));
    
    PackageManager pm = this.getPackageManager();
    if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) && !pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
        Toast.makeText(this, "Sorry, your device probably can't send SMS...", Toast.LENGTH_SHORT).show();
    } else{
        // 使用传入的号码和短信内容,不再硬编码
        smsManager.sendTextMessage(thenumber, null, mymsg, sentPending, deliveredPending);
        // 直接用全局TextView设置状态
        textStatus.setText("enable");
    }
}

4. 修复sendNackMsg方法

同样去掉冗余代码,使用全局TextView:

public void sendNackMsg(String phonenumber, String msg) {
    String SENT = "Message sent";
    String DELIVERED = "Message delivered";
    SmsManager smsManager = SmsManager.getDefault();
    Context curContext = this.getApplicationContext();
    
    PendingIntent sentPending = PendingIntent.getBroadcast(curContext, 0, new Intent(SENT), 0);
    curContext.registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context arg0, Intent arg1) {
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "Sent.", Toast.LENGTH_LONG).show();
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    Toast.makeText(getBaseContext(), "Not Sent: Generic failure.", Toast.LENGTH_LONG).show();
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    Toast.makeText(getBaseContext(), "Not Sent: No service (possibly, no SIM-card).", Toast.LENGTH_LONG).show();
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    Toast.makeText(getBaseContext(), "Not Sent: Null PDU.", Toast.LENGTH_LONG).show();
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    Toast.makeText(getBaseContext(), "Not Sent: Radio off (possibly, Airplane mode enabled in Settings).", Toast.LENGTH_LONG).show();
                    break;
            }
        }
    }, new IntentFilter(SENT));
    
    PendingIntent deliveredPending = PendingIntent.getBroadcast(curContext, 0, new Intent(DELIVERED), 0);
    curContext.registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context arg0, Intent arg1) {
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "Delivered.", Toast.LENGTH_LONG).show();
                    break;
                case Activity.RESULT_CANCELED:
                    Toast.makeText(getBaseContext(), "Not Delivered: Canceled.", Toast.LENGTH_LONG).show();
                    break;
            }
        }
    }, new IntentFilter(DELIVERED));
    
    PackageManager pm = this.getPackageManager();
    if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) && !pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
        Toast.makeText(this, "Sorry, your device probably can't send SMS...", Toast.LENGTH_SHORT).show();
    } else{
        smsManager.sendTextMessage(phonenumber, null, msg, sentPending, deliveredPending);
        textStatus.setText("disable");
    }
}

额外优化建议

  • 广播接收器重复注册问题:当前代码每次点击按钮都会注册新的广播接收器,容易导致内存泄漏。建议把广播接收器的注册移到onCreate中,或者使用PendingIntent.FLAG_UPDATE_CURRENT来复用已有的PendingIntent。
  • 权限申请:别忘了在Manifest中添加发送短信的权限:<uses-permission android:name="android.permission.SEND_SMS"/>,如果是Android 6.0以上,还要动态申请权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:09:06