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

Kotlin中AlarmManager.setExact()无法触发广播接收器求助

问题:AlarmReceiver的onReceive()始终未触发

已尝试多种方法让闹钟正常工作,AlarmReceiver类中的onReceive()始终未被调用,参考大量教程无果,已在API 24和34版本中测试。

相关代码

MainActivity代码

class MainActivity : ComponentActivity() {
    fun addAlarm() {
        val intent = Intent(this, AlarmReceiver::class.java)
        val pendingIntent = PendingIntent.getBroadcast(
            this,
            0,
            intent,
            PendingIntent.FLAG_IMMUTABLE)
        val timeToWakeupInMillis: Long = 3000//System.currentTimeMillis() + 3000
        val alarmManager = this.applicationContext.getSystemService(ALARM_SERVICE) as AlarmManager
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeToWakeupInMillis, pendingIntent)
    }

    // More functions here.
}

广播接收器类代码

class AlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        Toast.makeText(context,"Alarm!",Toast.LENGTH_LONG).show()
    }
}

AndroidManifest.xml权限配置

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>

权限申请逻辑

if (alarmManager.canScheduleExactAlarms() == false) {
  Intent().also { intent -> intent.action = ACTION_REQUEST_SCHEDULE_EXACT_ALARM
    this.startActivity(intent)
  }
}

代码可正常运行,setExact()调用无异常,但onReceive()始终未触发。


排查与解决方案

1. 确认广播接收器已在Manifest中注册

静态广播接收器必须在AndroidManifest.xml中声明,这是最容易遗漏的关键步骤:

<receiver
    android:name=".AlarmReceiver"
    android:exported="false">
    <!-- 若需接收系统广播可调整exported属性为true -->
</receiver>

2. 修正闹钟时间设置

当前代码中timeToWakeupInMillis = 3000对应的是1970年1月1日的历史时间,早已过期,AlarmManager不会触发过期的闹钟。需改为当前时间加上延迟:

val timeToWakeupInMillis: Long = System.currentTimeMillis() + 3000

3. 适配PendingIntent的FLAG(API 31+)

对于API 31及以上版本,若PendingIntent不需要后续修改,使用PendingIntent.FLAG_IMMUTABLE是正确的;如果后续需要更新PendingIntent内容,则需改用PendingIntent.FLAG_MUTABLE,同时确保项目的targetSdkVersion配置正确。

4. 检查电池优化与后台限制

  • 电池优化:部分厂商的电池优化策略会阻止后台闹钟触发,需引导用户将应用加入电池白名单:
    val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
    intent.data = Uri.parse("package:" + packageName)
    startActivity(intent)
    
    同时需在Manifest中添加对应权限:
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
    
  • 后台限制:API 26+对静态广播有更严格的系统限制,若上述方法无效,可考虑改用WorkManager实现定时任务,或者采用动态注册广播接收器的方式。

5. 确保权限已正确授予

在跳转权限设置页面后,需重新检查权限状态,只有确认权限已授予后再执行addAlarm():

if (alarmManager.canScheduleExactAlarms()) {
    addAlarm()
} else {
    // 提示用户完成权限授予操作
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:05:20