Android Studio中SMS广播接收器无法触发问题求助
我需要开发一款应用,收到特定号码或包含特定文本的短信时自动启动自身。已配置SMS Broadcast Receiver、AndroidManifest权限和MainActivity的Intent,但始终无法实现功能。测试用Pixel 7 Pro(开启调试),已授予SMS权限,应用无论前台、后台还是被杀死状态,收到短信后均无响应,LogCat中看不到SmsReceiver的日志。
现有代码配置
SmsReceiver.kt
package com....... import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.os.Build import android.provider.Telephony import android.telephony.SmsMessage import android.util.Log import android.os.Bundle import android.widget.Toast class SmsReceiver : BroadcastReceiver() { val SMS ="android.privider.Telephony.SMS_RECEIVED"; override fun onReceive(context: Context, intent: Intent) { if (intent.action == Telephony.Sms.Intents.SMS_RECEIVED_ACTION) { Log.d("SmsReceiver", "SMS received intent detected") val smsMessages = Telephony.Sms.Intents.getMessagesFromIntent(intent) for (message in smsMessages) { val sender = message.displayOriginatingAddress val messageBody = message.messageBody Log.d("SmsReceiver", "Sender: $sender") Log.d("SmsReceiver", "Message body: $messageBody") if (sender == "+43....." || messageBody.contains("Einsatzgebiet")) { Log.d("SmsReceiver", "Message received from: $sender") Log.d("SmsReceiver", "Message body: $messageBody") val launchIntent = Intent(context, MainActivity::class.java) launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) launchIntent.putExtra("sms_body", messageBody) context.startActivity(launchIntent) } } } } }
AndroidManifest.xml 权限配置
<uses-feature android:name="android.hardware.telephony" android:required="false" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.SEND_SMS" />
AndroidManifest.xml 接收器配置
<receiver android:name=".SmsReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver>
MainActivity.kt onCreate方法
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS), REQUEST_SMS_PERMISSION) } val smsBody = intent.getStringExtra("sms_body") if (smsBody != null) { Log.d(TAG, "SMS content: $smsBody") clipboardTextView.text = smsBody updateEinsatzInfo(smsBody) } loadClipboardButton.setOnClickListener { Log.d(TAG, "Load Clipboard button clicked") updateClipboardContent() }
MainActivity.kt 权限回调方法
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == REQUEST_SMS_PERMISSION) { if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { Log.d(TAG, "SMS permissions granted") } else { Log.e(TAG, "SMS permissions denied") } } else if (requestCode == REQUEST_CALL_PERMISSION) { if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { makePhoneCall() } else { Log.e(TAG, "Call permission denied") } } }
排查与解决步骤
1. 适配Android 8.0+的广播限制
从Android 8.0(API 26)开始,静态注册的广播接收器无法接收大部分隐式广播,包括android.provider.Telephony.SMS_RECEIVED,这是你接收器完全没触发的核心原因。
解决方法:改用动态注册广播接收器,在应用存活周期内注册/注销:
private lateinit var smsReceiver: SmsReceiver override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 动态注册短信接收器 smsReceiver = SmsReceiver() val intentFilter = IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION) registerReceiver(smsReceiver, intentFilter) // 原有权限请求代码... } override fun onDestroy() { super.onDestroy() // 注销接收器,避免内存泄漏 unregisterReceiver(smsReceiver) }
注意:动态注册仅在应用进程存活时有效,若需要后台(应用被杀死)也能触发,需结合前台服务实现。
2. 修正拼写错误
你的代码中定义了val SMS ="android.privider.Telephony.SMS_RECEIVED";,其中privider是拼写错误(正确为provider),虽然当前逻辑未使用这个变量,但建议修正避免后续问题。
3. 提升广播接收优先级
部分系统或第三方短信APP会抢占SMS_RECEIVED广播,可给接收器的intent-filter添加优先级:
<intent-filter android:priority="1000"> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter>
优先级范围为-1000到1000,数值越高接收优先级越高。
4. 验证权限是否真正生效
手动进入手机设置→应用信息→目标应用→权限,确认接收短信、读取短信权限已完全开启(部分系统会分步骤授权,需确保所有相关权限都通过)。
5. 用ADB命令测试广播触发
使用ADB命令直接发送测试广播,验证接收器是否正常工作:
adb shell am broadcast -a android.provider.Telephony.SMS_RECEIVED --es sms_body "Einsatzgebiet test" --es address "+43123456789"
如果LogCat中能看到接收器的日志,说明接收器逻辑正常,问题出在真实短信的接收环节。
6. 适配Android 12+的后台启动限制
从Android 12(API 31)开始,系统对后台启动Activity有严格限制,即使广播触发,直接调用startActivity可能被拦截。可修改启动逻辑:
// 在SmsReceiver的onReceive中修改启动代码 val launchIntent = Intent(context, MainActivity::class.java) launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP) launchIntent.putExtra("sms_body", messageBody) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT) } context.startActivity(launchIntent)
或者先启动前台服务,再在服务中启动Activity,能大幅降低被系统拦截的概率。
内容的提问来源于stack exchange,提问作者Mario Dittrich

