Android闹钟应用AlarmManager触发后WakeLock无法点亮屏幕如何解决
问题原因及修复方案
你当前的代码存在4个核心问题,逐个修复即可解决屏幕不点亮的问题:
1. WakeLock类型与释放时机错误
你当前使用的PowerManager.PARTIAL_WAKE_LOCK只会唤醒CPU,不会点亮屏幕,而且你在启动Activity后立刻释放WakeLock,此时Activity还未完成初始化,设备会直接回到休眠状态。
修复步骤:
首先在AndroidManifest.xml中添加基础权限:
<uses-permission android:name="android.permission.WAKE_LOCK" />
修改AlarmReceiver的WakeLock逻辑:
class AlarmReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { // 改用带亮屏标记的WakeLock val wakeLock: PowerManager.WakeLock = (context.getSystemService(Context.POWER_SERVICE) as PowerManager).run { newWakeLock( PowerManager.FULL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP or PowerManager.ON_AFTER_RELEASE, "MyApp::AlarmWakelockTag" ).apply { // 只持有30秒足够Activity完成启动,不需要申请10分钟 acquire(30*1000L) } } Toast.makeText(context, "Wake Up!", Toast.LENGTH_LONG).show() val alarmDisplayIntent = Intent(context, AlarmDisplayActivity::class.java) alarmDisplayIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP context.startActivity(alarmDisplayIntent) // 不要立刻释放,WakeLock会在30秒后自动释放,避免Activity未启动就休眠 } }
2. Activity缺少锁屏展示、亮屏的必要配置
Android 9及以下版本仅调用setTurnScreenOn(true)不生效,需要同时配置Window对应Flag,还要添加锁屏展示配置,否则设备锁屏状态下无法唤起亮屏。
修复后的AlarmDisplayActivity代码:
class AlarmDisplayActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_alarm_display) window.addFlags( WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or // 兼容低版本亮屏 WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or // 锁屏状态下也能展示 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or // 自动跳过无密码的系统锁屏 WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD ) // 高版本API兼容 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { setTurnScreenOn(true) setShowWhenLocked(true) // 如果需要跳过有密码的锁屏,可添加以下代码 // val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager // keyguardManager.requestDismissKeyguard(this, null) } } }
3. 后台启动Activity权限适配
Android 8.0开始对后台启动Activity做了限制,闹钟类应用需要在Manifest中添加特殊权限才能在后台唤起Activity:
在AndroidManifest.xml中添加以下权限:
<!-- 提升应用后台优先级,保证Android9及以上可正常唤起Activity --> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 可选:如果需要开机后保留闹钟配置添加该权限 --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
如果后续升级适配Android 12及以上版本,还需要补充精确闹钟权限:
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
4. 闹钟触发逻辑优化
你当前的代码如果设置的闹钟时间早于当前时间,会立刻触发,建议添加时间校验逻辑:
val alarmTime = Calendar.getInstance().apply { timeInMillis = System.currentTimeMillis() set(Calendar.HOUR_OF_DAY, alarmForm.time.get(Calendar.HOUR_OF_DAY)) set(Calendar.MINUTE, alarmForm.time.get(Calendar.MINUTE)) set(Calendar.SECOND, 0) // 如果设置的时间早于当前时间,自动调整为第二天同时间 if (timeInMillis < System.currentTimeMillis()) { add(Calendar.DAY_OF_YEAR, 1) } } alarmManager.setExact( AlarmManager.RTC_WAKEUP, alarmTime.timeInMillis, alarmIntent )
内容的提问来源于stack exchange,提问作者Al Ryan Acain
相关产品推荐
相关产品推荐

