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
相关产品推荐
相关产品推荐

