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,确保逻辑能完整执行:
- 创建处理短信的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(); // ... } } } }
- 在Manifest中注册Service:
<service android:name=".SmsProcessService" />
- 修改
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
相关产品推荐
相关产品推荐

