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

如何将BroadcastReceiver的Intent传递至Activity?短信接收问题排查

实现特定手机号验证码接收与Intent传递的解决方案及代码问题排查

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 use sms_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_RECEIVED receivers are ignored by the system. You must use dynamic registration.
  • Permission gaps: Your code requires RECEIVE_SMS and READ_SMS permissions. Android 6.0+ requires dynamic permission requests for these dangerous permissions.
  • Activity launch optimization: Using only FLAG_ACTIVITY_NEW_TASK will create multiple instances of SmsReport if the broadcast triggers multiple times. Add FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP to 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_SMS and READ_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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:18:46