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

Android中BroadcastReceiver无法接收SMS广播的问题排查

Android BroadcastReceiver 监听失效问题排查与解决

核心原因:Android 8.0+ 静态广播限制

从Android 8.0(API 26)开始,系统对静态注册的BroadcastReceiver实施严格限制,包括android.provider.Telephony.SMS_RECEIVED、android.intent.action.AIRPLANE_MODE在内的大部分隐式广播,不再允许通过Manifest静态注册接收,必须改用动态注册。

具体修复步骤

1. 移除Manifest中的静态广播注册

删除AndroidManifest.xml里MessagesReceiver对应的<receiver>标签,静态注册在8.0+版本对这类广播已完全失效。

2. 动态注册BroadcastReceiver

在MainActivity或生命周期稳定的组件(如Application)中动态注册接收器,示例代码:

public class MainActivity extends AppCompatActivity {
    private MessagesReceiver messagesReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化接收器
        messagesReceiver = new MessagesReceiver();

        // 注册短信接收广播
        IntentFilter smsFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
        smsFilter.setPriority(999); // 可选,设置优先级确保广播能被捕获
        registerReceiver(messagesReceiver, smsFilter);

        // 注册飞行模式广播(用于测试)
        IntentFilter airplaneFilter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        registerReceiver(messagesReceiver, airplaneFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 务必注销接收器,避免内存泄漏
        if (messagesReceiver != null) {
            unregisterReceiver(messagesReceiver);
        }
    }
}

3. 适配Android 13+权限要求

Android 13(API 33)新增POST_NOTIFICATIONS权限,同时短信监听需要RECEIVE_SMS和READ_SMS权限,先在Manifest中添加权限声明:

<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

再在代码中动态申请权限:

private static final int PERMISSION_REQUEST_CODE = 100;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 检查并申请权限
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED
            || ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.RECEIVE_SMS, Manifest.permission.POST_NOTIFICATIONS},
                PERMISSION_REQUEST_CODE);
    } else {
        // 权限已授予,注册广播
        registerReceivers();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == PERMISSION_REQUEST_CODE) {
        boolean allGranted = true;
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                allGranted = false;
                break;
            }
        }
        if (allGranted) {
            registerReceivers();
        } else {
            Toast.makeText(this, "需要权限才能接收短信", Toast.LENGTH_SHORT).show();
        }
    }
}

private void registerReceivers() {
    // 放置之前的动态注册逻辑
}

4. 确保MessagesReceiver实现正确

检查onReceive方法是否添加了日志输出,方便验证:

public class MessagesReceiver extends BroadcastReceiver {
    private static final String TAG = "MessagesReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "收到广播:" + intent.getAction());
        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) {
                        SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdu);
                        Log.d(TAG, "短信内容:" + sms.getMessageBody());
                    }
                }
            }
        } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())) {
            boolean isAirplaneMode = intent.getBooleanExtra("state", false);
            Log.d(TAG, "飞行模式状态:" + (isAirplaneMode ? "开启" : "关闭"));
        }
    }
}

额外注意事项

  • 动态注册的接收器会随组件(如Activity)销毁而失效,若需后台持续监听,可结合Foreground Service注册,避免被系统回收。
  • 短信广播优先级不要超过999,否则可能被系统拦截。
  • Android 12+对后台启动限制更严格,确保应用在前台时注册接收器,或通过前台服务维持注册状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 16:13:14