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

Android 10+无通知短信监听:杀进程/重启后组件保活咨询

无通知短信监听+后台保活全版本适配方案

针对你遇到的「应用被杀/重启后组件停止、Android 10+后台无通知运行、全版本短信监听」问题,直接给你可行的解决方案:

一、核心适配逻辑

Android各版本后台限制越来越严,加上厂商的电池优化策略,单纯靠静态广播+普通Service根本扛不住。得用「动态注册/辅助服务监听短信+开机自启动+厂商权限适配」的组合拳,才能满足需求。

二、全版本短信监听实现

1. Android 4.4~7.1

静态注册SMS_RECEIVED还能用,但为了统一后续版本逻辑,建议直接用动态注册:在Service或主Activity里注册广播接收器,进程存活时就能收到短信。

2. Android 8.0~9.0

静态隐式广播被系统限制,必须动态注册SMS_RECEIVED。但普通后台Service容易被杀死,要是不想显示前台通知,直接换**AccessibilityService(辅助服务)**更靠谱。

3. Android 10+

后台启动Service限制极严,普通Service存活时间短,前台Service又必须弹通知。这里给两个方案:

方案1:AccessibilityService(无通知首选)

辅助服务只要用户开启,就能长期在后台运行,无需显示通知,还能监听短信事件:

class SmsAccessibilityService : AccessibilityService() {
    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        // 监听短信通知栏事件
        if (event.eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
            val smsContent = event.text.joinToString("\n")
            Log.i("SmsAccess", "收到短信:$smsContent")
            // 调用你的postSms方法处理短信
            postSms(smsContent, "", "", this)
        }
        // 若需更精准提取短信内容,可监听短信APP的界面变化(需适配不同厂商短信应用)
    }

    override fun onInterrupt() {}

    override fun onServiceConnected() {
        super.onServiceConnected()
        val serviceInfo = AccessibilityServiceInfo().apply {
            eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED
            feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC
            flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
        }
        setServiceInfo(serviceInfo)
    }
}

在Manifest中注册该服务:

<service
    android:name=".SmsAccessibilityService"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
    android:exported="false">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility_config" />
</service>

在res/xml目录下创建accessibility_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeNotificationStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagIncludeNotImportantViews"
    android:description="@string/accessibility_desc"
    android:notificationTimeout="100" />

在strings.xml添加辅助服务描述(需清晰告知用户用途,降低授权门槛):

<string name="accessibility_desc">用于后台监听短信,不会显示任何通知,仅在后台运行</string>

方案2:TelephonyManager监听(Android 12+专属)

Android 12+提供TelephonyManager.registerTelephonyCallbackAPI,可直接监听短信,比广播更稳定:

class SmsMonitorService : Service() {
    private lateinit var telephonyManager: TelephonyManager
    private lateinit var smsCallback: TelephonyCallback.SmsCallback

    override fun onCreate() {
        super.onCreate()
        telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
        smsCallback = object : TelephonyCallback.SmsCallback() {
            override fun onSmsReceived(smsMessage: SmsMessage) {
                super.onSmsReceived(smsMessage)
                val msg = smsMessage.messageBody
                val number = smsMessage.displayOriginatingAddress
                val date = millisToDate(smsMessage.timestampMillis)!!
                Log.i("SmsMonitor", "短信内容:$msg,号码:$number")
                postSms(msg, number, date, this@SmsMonitorService)
            }
        }
        // 先检查权限
        if (checkSelfPermission(Manifest.permission.READ_SMS) == PackageManager.PERMISSION_GRANTED) {
            telephonyManager.registerTelephonyCallback(mainExecutor, smsCallback)
        }
    }

    override fun onBind(intent: Intent?): IBinder? = null

    override fun onDestroy() {
        super.onDestroy()
        telephonyManager.unregisterTelephonyCallback(smsCallback)
    }
}

注意:该方案需保证Service存活,Android 10+若不用前台服务,进程很快会被回收。Android 14支持临时前台服务(无需通知),但旧版本仍需配合辅助服务或厂商权限才能稳定运行。

三、保活:杀后台/重启后继续运行

1. 开机自启动

静态注册BOOT_COMPLETED广播,设备重启后要么启动服务,要么引导用户开启辅助功能:

class BootReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == Intent.ACTION_BOOT_COMPLETED || intent.action == "android.intent.action.QUICKBOOT_POWERON") {
            // 检查辅助服务是否开启
            val isAccessEnabled = isAccessibilityServiceEnabled(context, SmsAccessibilityService::class.java)
            if (!isAccessEnabled) {
                // 跳转到辅助功能设置页
                val settingsIntent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
                settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                context.startActivity(settingsIntent)
            } else {
                // 启动监听服务(若使用Telephony方案)
                context.startService(Intent(context, SmsMonitorService::class.java))
            }
        }
    }

    // 检查辅助服务是否开启的工具方法
    private fun isAccessibilityServiceEnabled(context: Context, serviceClass: Class<out AccessibilityService>): Boolean {
        val accessibilityManager = context.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
        val enabledServices = accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK)
        for (serviceInfo in enabledServices) {
            if (serviceInfo.resolveInfo.serviceInfo.name == serviceClass.name) {
                return true
            }
        }
        return false
    }
}

在Manifest中注册该广播:

<receiver
    android:name=".BootReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>

2. 厂商权限适配

小米、华为、OPPO、Vivo等品牌有自定义电池优化策略,必须引导用户开启以下权限才能保证后台存活:

  • 自启动权限
  • 忽略电池优化(后台活动权限)
  • 后台弹出界面权限(部分机型)

以小米为例,跳转自启动设置页的代码:

fun openMiuiAutoStart(context: Context) {
    try {
        val intent = Intent()
        intent.component = ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")
        context.startActivity(intent)
    } catch (e: Exception) {
        // 跳转应用详情页兜底
        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
        intent.data = Uri.fromParts("package", context.packageName, null)
        context.startActivity(intent)
    }
}

其他厂商的跳转逻辑可通过查询对应包名和类名实现。

3. 额外保活技巧

  • 用WorkManager定期检查服务是否存活,未存活则重启。
  • 在Service的onDestroy方法中发送自定义广播尝试重启自身(Android 8+可能失效,但部分机型仍有效)。

四、现有代码优化

1. BroadcastReceiver拆分

你当前的RestarterReceiver同时处理短信和重启逻辑,职责混乱,建议拆分:

// 专门处理短信的动态广播接收器
class SmsReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action != "android.provider.Telephony.SMS_RECEIVED") return
        
        val bundle = intent.extras ?: return
        val pdus = bundle["pdus"] as? Array<Any> ?: return
        val msgs = pdus.map { SmsMessage.createFromPdu(it as ByteArray) }
        
        val fullMsg = msgs.joinToString("") { it.messageBody }
        val number = msgs.firstOrNull()?.displayOriginatingAddress ?: ""
        val date = msgs.firstOrNull()?.timestampMillis?.let { millisToDate(it) } ?: ""
        
        Log.i("SmsReceiver", "收到短信:$fullMsg,号码:$number,时间:$date")
        postSms(fullMsg, number, date, context)
    }
}

2. Manifest优化

删除静态注册的SMS_RECEIVED(Android 8+无效),添加必要权限:

<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<!-- 若使用前台服务,添加该权限:<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> -->

五、权限申请流程

  1. Android 6+动态申请RECEIVE_SMS和READ_SMS权限。
  2. 引导用户开启辅助功能(使用Accessibility方案时)。
  3. 引导用户开启厂商的自启动、忽略电池优化权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:31:07