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

APP关闭时如何从Broadcast Receiver向普通Java类传递短信数据?

问题分析与解决方案

问题根源

你通过静态注册的SmsReceiver在APP进程被销毁后,系统收到短信会重启APP进程并实例化SmsReceiver,但此时MainActivity未初始化,SmsEasy实例也没创建,导致SmsReceiver中的静态变量smsFetcher未被赋值,触发空指针。静态变量的生命周期和进程绑定,进程销毁后静态变量会被清空,重启后没有代码调用initSmsFetcher,因此出现空值。


解决方案

方案一:在Receiver内部直接处理短信逻辑(适合简单业务)

把原本在SmsEasy中的处理逻辑直接移到SmsReceiver的onReceive方法中,无需依赖外部对象,进程重启后仍能正常执行:

public class SmsReceiver extends BroadcastReceiver {
    @SuppressLint("UnsafeProtectedBroadcastReceiver")
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle extras = intent.getExtras();
        if (extras != null){
            Object[] smsextras = (Object[]) extras.get( "pdus" );

            for (Object smsextra : smsextras) {
                SmsMessage smsmsg = SmsMessage.createFromPdu((byte[]) smsextra);
                // 直接处理短信逻辑
                handleSmsContent(smsmsg, context);
            }
        }
    }

    private void handleSmsContent(SmsMessage smsMessage, Context context) {
        String sender = smsMessage.getOriginatingAddress();
        String content = smsMessage.getMessageBody();
        // 这里写你的业务逻辑,比如保存到本地、发送通知等
    }
}

方案二:启动Service处理复杂逻辑(适合耗时/异步任务)

如果短信处理逻辑复杂或需要异步执行,可在onReceive中启动IntentService或ForegroundService,确保逻辑能完整执行:

  1. 创建处理短信的Service:
public class SmsProcessService extends IntentService {
    public static final String EXTRA_SMS = "extra_sms";

    public SmsProcessService() {
        super("SmsProcessService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            SmsMessage smsMessage = intent.getParcelableExtra(EXTRA_SMS);
            if (smsMessage != null) {
                // 在这里执行复杂处理逻辑
                String content = smsMessage.getMessageBody();
                // ...
            }
        }
    }
}
  1. 在Manifest中注册Service:
<service android:name=".SmsProcessService" />
  1. 修改SmsReceiver的onReceive方法:
@Override
public void onReceive(Context context, Intent intent) {
    Bundle extras = intent.getExtras();
    if (extras != null){
        Object[] smsextras = (Object[]) extras.get( "pdus" );

        for (Object smsextra : smsextras) {
            SmsMessage smsmsg = SmsMessage.createFromPdu((byte[]) smsextra);
            // 启动Service处理
            Intent serviceIntent = new Intent(context, SmsProcessService.class);
            serviceIntent.putExtra(SmsProcessService.EXTRA_SMS, smsmsg);
            ContextCompat.startForegroundService(context, serviceIntent);
        }
    }
}

方案三:动态注册Receiver(仅APP运行时处理)

如果仅需要APP在前台运行时处理短信,可改用动态注册,APP销毁后Receiver自动注销,不会触发:

修改MainActivity:

public class MainActivity extends AppCompatActivity {
    private SmsReceiver smsReceiver;
    private SmsEasy smsEasy;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        smsEasy = new SmsEasy();
        smsReceiver = new SmsReceiver();
        smsReceiver.initSmsFetcher(smsEasy);
        // 动态注册短信监听
        IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
        registerReceiver(smsReceiver, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 注销Receiver
        if (smsReceiver != null) {
            unregisterReceiver(smsReceiver);
        }
    }
}

同时移除Manifest中对SmsReceiver的静态注册。


方案选择建议

  • APP关闭后仍需处理短信:选择方案一或方案二
  • 仅APP运行时处理短信:选择方案三

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:06:01