Android 11(API 30)模拟器中AlarmManager无法工作问题排查
问题原因及解决方案
你的闹钟在Android 11及以上版本失效,核心原因有两个:
1. Android 10+的后台启动Activity限制
从API 29开始,Android禁止后台应用直接启动Activity,哪怕是闹钟触发的PendingIntent.getActivity也会被系统拦截。旧版本(API25)没有这个限制,所以能正常运行。
2. API30+对PendingIntent标记的要求
API30及以上版本中,创建PendingIntent必须显式指定FLAG_IMMUTABLE或FLAG_MUTABLE标记,仅用FLAG_UPDATE_CURRENT可能导致PendingIntent无法正常触发。
另外要注意:如果当前时间已经过了你设置的14:20,闹钟会自动推迟到第二天触发,这也可能让你误以为功能失效。
修复步骤
第一步:改用BroadcastReceiver中转
创建一个广播接收器接收闹钟触发事件,再由接收器启动Activity,绕过后台启动限制:
class AlarmReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val activityIntent = Intent(context, ReminderAlarmActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP) } context?.startActivity(activityIntent) } }
第二步:在Manifest中注册接收器
在AndroidManifest.xml里添加接收器的注册信息:
<receiver android:name=".AlarmReceiver" android:exported="false" />
第三步:修改闹钟设置代码
替换原有的PendingIntent.getActivity为getBroadcast,并添加适配API版本的标记:
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager val intent = Intent(applicationContext, AlarmReceiver::class.java) // 根据API版本选择合适的PendingIntent标记 val pendingFlags = 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(applicationContext, 123456, intent, pendingFlags) val calendar = Calendar.getInstance() calendar.set(Calendar.HOUR_OF_DAY, 14) calendar.set(Calendar.MINUTE, 20) // 如果当前时间已过设置时间,自动推迟到第二天 if (calendar.timeInMillis < System.currentTimeMillis()) { calendar.add(Calendar.DAY_OF_YEAR, 1) } val alarmClockInfo = AlarmManager.AlarmClockInfo(calendar.timeInMillis, null) alarmManager.setAlarmClock(alarmClockInfo, pendingIntent)
内容的提问来源于stack exchange,提问作者morteza moradi
相关产品推荐
相关产品推荐

