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
相关产品推荐
相关产品推荐

