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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 09:12:07