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

AlarmManager在应用手动关闭后无法触发,应如何调整代码?

故障根因
  • 你使用了Activity内部动态注册的匿名广播接收器:应用被手动关闭、Activity销毁时,该动态注册的接收器会被系统直接回收注销,无法接收到闹钟触发的广播
  • PendingIntent 使用了无效flag:Android 12及以上系统要求明确指定PendingIntent的可变性属性,你传入的0属于非法配置,会导致闹钟触发时无法匹配到对应响应逻辑
  • 广播未在AndroidManifest中静态注册:只有静态注册的广播接收器才能在应用进程被杀后,依然响应系统发出的目标广播
具体修改步骤

1. 单独创建广播接收器类

不要将接收器逻辑写在Activity内部,单独创建顶层类:

class AlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == "SET_ALARM") {
            val mp = MediaPlayer.create(context, R.raw.music)
            mp.start()
        }
    }
}

2. 在AndroidManifest.xml中静态注册广播

在<application>标签内添加接收器配置:

<receiver
    android:name=".AlarmReceiver"
    android:exported="false">
    <intent-filter>
        <action android:name="SET_ALARM" />
    </intent-filter>
</receiver>

同时添加闹钟相关权限到Manifest的根标签下:

<!-- Android 12及以上需要的精确闹钟调度权限 -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<!-- Android 14及以上额外需要的权限 -->
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />

3. 修改MainActivity逻辑

删除原有的动态注册广播代码,调整PendingIntent配置、添加权限判断逻辑:

class MainActivity : ComponentActivity() {
    private lateinit var alarmManager: AlarmManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            alarmManager = getSystemService(ALARM_SERVICE) as AlarmManager
            val calendar = Calendar.getInstance()
            calendar.add(Calendar.MINUTE, 1)

            // 明确指定广播接收器类
            val alarmIntent = Intent(this, AlarmReceiver::class.java)
            alarmIntent.action = "SET_ALARM"

            // 配置适配全版本的PendingIntent flag
            val pendingFlag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            } else {
                PendingIntent.FLAG_UPDATE_CURRENT
            }
            val pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, pendingFlag)

            Column(
                Modifier.fillMaxWidth(),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Button(onClick = {
                    // Android 12及以上需要先判断精确闹钟权限
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                        if (alarmManager.canScheduleExactAlarms()) {
                            alarmManager.setAndAllowWhileIdle(
                                AlarmManager.RTC_WAKEUP,
                                calendar.timeInMillis,
                                pendingIntent
                            )
                        } else {
                            // 引导用户跳转授权精确闹钟权限
                            val intent = Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM)
                            startActivity(intent)
                        }
                    } else {
                        alarmManager.setAndAllowWhileIdle(
                            AlarmManager.RTC_WAKEUP,
                            calendar.timeInMillis,
                            pendingIntent
                        )
                    }
                }) {
                    Text("1分钟后播放音乐")
                }
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 12:15:03