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

Android SMS BroadcastReceiver运行一段时间后停止响应问题排查

解决短信转发应用Broadcast Receiver停止响应的问题

本质原因

Android 8.0(API 26)开始,系统对静态注册的隐式广播(比如SMS_RECEIVED)做了严格限制。就算设备处于充电状态,应用闲置1-2小时后,后台进程会被系统回收,静态注册的接收器也就跟着失效了——只有当你打开应用,进程重新启动,接收器才会再次工作。

核心解决方案

1. 改用前台Service+动态注册广播

静态注册的路子已经走不通,必须用前台Service来承载动态注册的广播接收器,前台Service因为有常驻通知,系统不会轻易杀死它:

  • 先创建一个前台Service类:
class SmsGuardService : Service() {
    private lateinit var smsReceiver: SmsReceiver

    override fun onCreate() {
        super.onCreate()
        // 初始化并注册短信接收器
        smsReceiver = SmsReceiver()
        val smsFilter = IntentFilter("android.provider.Telephony.SMS_RECEIVED")
        smsFilter.priority = 999 // 设高优先级,确保能抢到短信事件
        registerReceiver(smsReceiver, smsFilter)

        // 启动前台通知(Android 8.0+必须创建通知渠道)
        val channel = NotificationChannel(
            "sms_forward_channel",
            "短信转发服务",
            NotificationManager.IMPORTANCE_LOW
        )
        getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
        
        val notification = NotificationCompat.Builder(this, "sms_forward_channel")
            .setSmallIcon(R.drawable.ic_service_notify)
            .setContentTitle("短信转发服务运行中")
            .setContentText("持续监听短信")
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .build()
        
        startForeground(1001, notification)
    }

    override fun onDestroy() {
        super.onDestroy()
        // 销毁时注销接收器,避免内存泄漏
        unregisterReceiver(smsReceiver)
    }

    override fun onBind(intent: Intent): IBinder? = null
}
  • 在Manifest里注册Service,同时声明前台服务类型(Android 12+要求):
<service
    android:name=".SmsGuardService"
    android:foregroundServiceType="dataSync"
    android:exported="false" />
  • 在应用启动的Activity里启动这个Service(比如MainActivity的onCreate方法):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(Intent(this, SmsGuardService::class.java))
} else {
    startService(Intent(this, SmsGuardService::class.java))
}

2. 申请忽略电池优化权限

就算用了前台Service,部分厂商的定制系统还是会偷偷杀后台,所以要引导用户给应用开「忽略电池优化」权限:

  • 先在Manifest加权限:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
  • 代码里检查并跳转设置页面:
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
    val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
    intent.data = Uri.parse("package:$packageName")
    startActivity(intent)
}

3. 适配国内厂商的后台管理

小米、华为、OPPO这些厂商有自己的后台管控逻辑,必须让用户手动设置:

  • 把应用加入「后台运行白名单」
  • 关闭应用的「智能省电」「深度睡眠」模式
  • 开启应用的「自启动权限」
    这些设置入口每个厂商不一样,你可以在应用里加个引导页面,告诉用户怎么操作。

为什么静态注册没用?

Android 8.0之后,只有少数系统级广播允许静态注册(比如开机广播),SMS_RECEIVED不在这个列表里。当应用进程被回收,静态接收器不会被系统唤醒——只有应用有活跃组件(比如前台Service)时,动态注册的接收器才能持续工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 00:46:00