React Native后台SMS广播监听集成故障排查与修复指导
React Native SMS广播监听器(后台运行)修正方案
核心问题梳理
你的代码存在以下关键问题导致无法捕获短信:
- 广播接收器注册逻辑混乱(静态注册指向不存在的类,动态创建后未注册)
- 权限未动态申请(Android 6.0+需要运行时权限)
- 无头任务JS模块导出错误
- 广播接收器属性配置错误
- SmsMessage解析的API兼容性问题
具体修正步骤
1. 修复广播接收器注册逻辑
方案:使用静态注册独立BroadcastReceiver(适合后台运行场景)
创建独立的SMSReceiver.java类,放在com.android_sms_listner路径下:
package com.android_sms_listner; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.telephony.SmsMessage; import com.facebook.react.HeadlessJsTaskService; public class SMSReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if ("android.provider.Telephony.SMS_RECEIVED".equals(intent.getAction())) { Bundle bundle = intent.getExtras(); if (bundle != null) { Object[] pdus = (Object[]) bundle.get("pdus"); if (pdus != null) { for (Object pdu : pdus) { // 兼容API 23+的解析方式 String format = bundle.getString("format"); SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdu, format); String messageBody = sms.getMessageBody(); String sender = sms.getOriginatingAddress(); // 触发无头任务 Intent headlessIntent = new Intent(context, SMSListnerHeadlessTask.class); headlessIntent.putExtra("messageBody", messageBody); headlessIntent.putExtra("sender", sender); HeadlessJsTaskService.acquireWakeLockNow(context); context.startService(headlessIntent); } } } } } }
修正AndroidManifest.xml中的接收器配置
将原receiver替换为以下内容(注意类名改为SMSReceiver,exported设为true):
<receiver android:name="com.android_sms_listner.SMSReceiver" android:exported="true"> <intent-filter android:priority="999"> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>
注:设置
android:priority="999"确保你的接收器优先于其他应用捕获短信(可选,但推荐)
2. 移除SMSListenerModule中冗余的动态广播代码
原SMSListenerModule中的startSMSListener方法创建了局部BroadcastReceiver但未注册,直接删除该方法,保留必要的工具方法:
public class SMSListenerModule extends ReactContextBaseJavaModule { private final ReactApplicationContext reactContext; public SMSListenerModule(ReactApplicationContext reactContext) { super(reactContext); this.reactContext = reactContext; } @Override public String getName() { return "SMSListener"; } // 保留需要的Native方法,不需要可删除 @ReactMethod public void show() { Toast.makeText(reactContext, "Hi from Module file", Toast.LENGTH_LONG).show(); Log.d("Show", "From show"); } }
3. 动态申请运行时权限
在React Native JS层添加权限申请逻辑,比如在App启动时:
import { PermissionsAndroid, Platform } from 'react-native'; const requestSMSPermissions = async () => { if (Platform.OS === 'android') { try { const granted = await PermissionsAndroid.requestMultiple([ PermissionsAndroid.PERMISSIONS.RECEIVE_SMS, PermissionsAndroid.PERMISSIONS.READ_SMS, ]); return granted[PermissionsAndroid.PERMISSIONS.RECEIVE_SMS] === PermissionsAndroid.RESULTS.GRANTED && granted[PermissionsAndroid.PERMISSIONS.READ_SMS] === PermissionsAndroid.RESULTS.GRANTED; } catch (err) { console.warn(err); return false; } } return true; }; // 在App组件中调用 useEffect(() => { requestSMSPermissions(); }, []);
4. 修复无头任务JS模块导出错误
原SMSListenerTask.js错误导出了NativeModule,应导出任务处理函数:
const SMSListenerTask = async (taskData) => { const { messageBody, sender } = taskData; console.warn(`Received SMS from ${sender}: ${messageBody}`); console.warn("Headless task executed"); }; module.exports = SMSListenerTask;
5. 确保HeadlessTaskService在Manifest中注册
在AndroidManifest.xml的<application>标签内添加:
<service android:name="com.android_sms_listner.SMSListnerHeadlessTask" />
6. 优化HeadlessTaskService的唤醒锁处理
在SMSListnerHeadlessTask.java中确保唤醒锁正确释放:
public class SMSListnerHeadlessTask extends HeadlessJsTaskService { @Override protected HeadlessJsTaskConfig getTaskConfig(Intent intent) { Bundle extras = intent.getExtras(); WritableMap data = Arguments.createMap(); if (extras != null) { String messageBody = extras.getString("messageBody"); String sender = extras.getString("sender"); data.putString("messageBody", messageBody); data.putString("sender", sender); } return new HeadlessJsTaskConfig( "SMSListenerTask", data, 5000, true ); } @Override public void onDestroy() { super.onDestroy(); HeadlessJsTaskService.releaseWakeLockNow(this); } }
测试验证步骤
- 重新编译运行应用:
npx react-native run-android - 授予应用短信权限
- 关闭应用(退到后台或完全关闭)
- 发送测试短信到设备,通过
adb logcat | grep ReactNativeJS查看后台日志
内容的提问来源于stack exchange,提问作者mFarhan
相关产品推荐
相关产品推荐

