Android点击Active/Deactive按钮后TextView无法正常更新问题求助
解决短信发送与TextView状态更新异常问题
我帮你梳理下代码里的几个关键问题,以及对应的修复方案:
核心问题分析
Switch语句缺少
break:你的onClick方法中,case R.id.button2执行完后没有加break,导致代码会继续执行case R.id.button4的逻辑——也就是说,不管你点击哪个按钮,最终都会调用sendNackMsg把TextView设为“disable”,这就是状态一直不变的根本原因。重复调用
setContentView:在sendMsg方法里你又执行了setContentView(R.layout.activity_main),这会重新加载整个布局,导致你之前初始化的控件引用全部失效,后续的setText其实是给新创建的TextView设置的,界面上显示的还是旧的控件,所以看不到状态变化。硬编码短信参数:
sendMsg里调用smsManager.sendTextMessage时用了硬编码的号码和内容,没有使用传入的thenumber和mymsg,导致点击按钮发送的内容不符合预期。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
相关产品推荐
相关产品推荐

