如何将BroadcastReceiver的Intent传递至Activity?短信接收问题排查
Hey there, let's break down your problem step by step. First, we'll fix the issues in your existing code, then walk through how to properly implement SMS reception for a specific number and pass data via Intent.
一、现有代码中的核心问题
Let's go through the bugs and compatibility issues in your code:
- 字符串比较错误: You used
sms_str == "333"to check the verification code. In Java,==compares object references, not string content. You should usesms_str.equals("333")instead. - 短信内容拼接逻辑错误: You're appending all SMS content from all senders to
sms_str, but the sender check is inside the loop. This can mix content from non-target numbers if multiple SMS are received in one broadcast (e.g., long SMS split into parts). - Dangerous SMS deletion logic: You're deleting the entire thread of messages from the target number, which will erase all historical messages from that sender. Also, Android 10+ restricts SMS read/write permissions heavily, so this operation will likely fail.
- BroadcastReceiver compatibility: From Android 8.0 (API 26), statically registered
SMS_RECEIVEDreceivers are ignored by the system. You must use dynamic registration. - Permission gaps: Your code requires
RECEIVE_SMSandREAD_SMSpermissions. Android 6.0+ requires dynamic permission requests for these dangerous permissions. - Activity launch optimization: Using only
FLAG_ACTIVITY_NEW_TASKwill create multiple instances ofSmsReportif the broadcast triggers multiple times. AddFLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOPto avoid duplicates.
二、修正后的完整实现代码
Step 1: Add permissions to AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_SMS" /> <!-- Register your target activity (if not already done) --> <activity android:name=".SmsReport" />
Step 2: Dynamically register the BroadcastReceiver
Do this in your main Activity (e.g., MainActivity) to ensure compatibility with Android 8.0+:
public class MainActivity extends AppCompatActivity { private MySMSBroadCastReceiver smsReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Request SMS permissions first (for Android 6.0+) if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS}, 100); } else { registerSMSReceiver(); } } private void registerSMSReceiver() { smsReceiver = new MySMSBroadCastReceiver(); IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); filter.setPriority(1000); // Ensure we receive the broadcast first registerReceiver(smsReceiver, filter); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100 && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { registerSMSReceiver(); } } @Override protected void onDestroy() { super.onDestroy(); // Unregister to avoid memory leaks if (smsReceiver != null) { unregisterReceiver(smsReceiver); } } }
Step 3: Fixed BroadcastReceiver code
public class MySMSBroadCastReceiver extends BroadcastReceiver { private static final String SPECIFIC_PHONE_NUMBER = "+989033001001"; private static final String TARGET_VERIFICATION_CODE = "333"; @Override public void onReceive(Context context, Intent intent) { // Validate the broadcast action if (!"android.provider.Telephony.SMS_RECEIVED".equals(intent.getAction())) { return; } Bundle bundle = intent.getExtras(); if (bundle == null) return; Object[] pdus = (Object[]) bundle.get("pdus"); if (pdus == null || pdus.length == 0) return; StringBuilder smsContent = new StringBuilder(); boolean isTargetSender = false; // Handle split SMS (long messages) for (Object pdu : pdus) { SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu); if (smsMessage == null) continue; String sender = smsMessage.getOriginatingAddress(); // Match the target number (you can normalize format, e.g., remove spaces/+) if (SPECIFIC_PHONE_NUMBER.equals(sender)) { isTargetSender = true; smsContent.append(smsMessage.getMessageBody()); } } // Only process if it's the target sender if (!isTargetSender) return; String smsStr = smsContent.toString(); // Show feedback if (TARGET_VERIFICATION_CODE.equals(smsStr)) { Toast.makeText(context, "验证码验证成功!", Toast.LENGTH_LONG).show(); } else { Toast.makeText(context, "收到目标号码短信:" + smsStr, Toast.LENGTH_LONG).show(); } // Pass data to SmsReport Activity Intent reportIntent = new Intent(context, SmsReport.class); reportIntent.putExtra("msg", smsStr); // Prevent multiple activity instances reportIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(reportIntent); // Intercept the broadcast (note: high Android versions may restrict this) abortBroadcast(); } }
三、简易版特定手机号短信接收代码
If you just need a minimal implementation to receive and read SMS from a specific number:
public class SimpleSMSReceiver extends BroadcastReceiver { private final String TARGET_PHONE = "+989033001001"; @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); if (bundle == null) return; Object[] pdus = (Object[]) bundle.get("pdus"); for (Object pdu : pdus) { SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdu); String sender = sms.getOriginatingAddress(); String content = sms.getMessageBody(); // Match target number (add format normalization if needed) if (TARGET_PHONE.equals(sender)) { Log.d("SMSReceiver", "Received target SMS: " + content); // Pass data to your activity Intent i = new Intent(context, YourTargetActivity.class); i.putExtra("sms_content", content); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); abortBroadcast(); break; } } } }
四、带源码的应用参考思路
If you want a full working demo app, build one with these core components:
- Dynamic permission request for
RECEIVE_SMSandREAD_SMS - Dynamic BroadcastReceiver registration
- Target phone number matching (with format normalization)
- SMS content extraction (use regex to pull verification codes if needed)
- Intent data passing to the target activity
You don't need external libraries for this—all logic can be implemented with Android's built-in APIs, keeping your code lightweight and controllable.
内容的提问来源于stack exchange,提问作者Mehran

