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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:36:05