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

Android AlarmManager定时调度失效 动态注册Receiver无法接收广播问题

问题修复方案

核心问题原因

  • 你构造的是指向Receiver类的显式广播Intent,而你的Receiver仅做了动态注册、未在Manifest中声明,系统无法识别该组件,导致Alarm触发时广播发送失败。
  • 动态注册Receiver时使用的IntentFilter为空,没有匹配任何广播Action,就算是隐式广播也无法接收。

修复步骤

  1. 修改广播Intent为隐式Intent,仅指定Action不指定组件类
  2. 给IntentFilter添加对应Action的匹配规则
  3. 可选适配高版本系统的权限要求

修复后核心代码

import android.app.AlarmManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.getSystemService
import kotlin.time.ExperimentalTime

class Receiver: BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        Log.d("Test", "ACTION: ${intent?.action}")
    }
}

@ExperimentalTime
class Test: AppCompatActivity() {

    private val receiver = Receiver()
    private lateinit var alarmManager: AlarmManager
    // 自定义广播Action,建议加上应用包名避免和其他应用冲突
    private val ACTION_TEST = "com.your.app.package.TEST"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        alarmManager = getSystemService()!!

        // 给过滤器添加对应Action匹配规则
        val filter = IntentFilter(ACTION_TEST)
        registerReceiver(receiver, filter)

        // 构造隐式广播Intent,仅指定Action不指定Receiver类
        val intent = Intent(ACTION_TEST)

        val pIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)

        val timestamp = System.currentTimeMillis() + 10000
        Log.d("Test", "SCHEDULE: $timestamp")

        // 适配Android 6.0+低电耗模式,需要在空闲状态也触发闹钟可使用setExactAndAllowWhileIdle
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timestamp, pIntent)
        } else {
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, timestamp, pIntent)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(receiver)
    }
}

额外适配说明

  • 如果运行设备是Android 12(API 31)及以上版本,需要在AndroidManifest.xml中添加精确闹钟权限声明:
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
    
  • 动态注册的Receiver生命周期和当前Activity绑定,如果Activity被销毁Receiver也会同步注销,闹钟触发时就无法收到广播,如果需要在后台接收广播仍需在Manifest中注册Receiver。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 17:36:04