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

三星Galaxy Z Flip3更新后AlarmManager失效问题求助

三星Galaxy Z Flip3系统更新后AlarmManager失效问题

我的应用在三星Galaxy Z Flip3上原本运行正常,系统更新后出现异常:只有保持手机唤醒且应用处于前台(需持续充电,完全不可行)时,闹钟通知才能正常触发。此前通过“电池和设备维护”设置应用永不休眠可解决类似问题,但这次该设置似乎被系统忽略。

以下是我编写的setAlarm代码,包含多种已尝试但注释掉的方案:

fun setAlarm(timeInMillis: Long) {
    val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
    val intent = Intent(this, MyAlarm::class.java)
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    val pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_MUTABLE)
    //alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent)
    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent)
    //alarmManager!!.set(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent)
/*
    alarmManager!!.setAlarmClock(
        AlarmManager.AlarmClockInfo(
            timeInMillis,
            null
        ), pendingIntent )
*/
    /*
    if (Build.VERSION.SDK_INT < 23) {
        if (Build.VERSION.SDK_INT >= 19) {
            if(System.currentTimeMillis()<startTime)
                alarmManager.setExact(AlarmManager.RTC_WAKEUP, startTime, pendingIntent);
        } else {
            if(System.currentTimeMillis()<startTime)
                alarmManager.set(AlarmManager.RTC_WAKEUP, startTime, pendingIntent);
        }
    } else {
        if(System.currentTimeMillis()<startTime)
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, startTime, pendingIntent);
    }

     */
    toastGeneral("""Alarm is set""")
}

补充发现

设置闹钟后按电源键熄屏,数小时后闹钟仍能正常触发;但设置闹钟后返回主屏幕或切换至其他应用,仅几分钟后闹钟就无法触发,再次打开应用时则立即执行闹钟逻辑。想知道这两种场景下应用状态的差异,以及如何让闹钟在应用处于此类状态时正常触发。

后续跟进(2023年9月15日)

发布问题已过去一个月,超100人浏览但无人回复。求分享在三星One UI 5.1.1系统的Flip手机上能正常唤醒应用的Kotlin代码。


解决方案与分析

三星系统更新的改动推测

三星One UI 5.1.1大概率进一步收紧了后台应用的资源管控策略:针对切换到后台而非直接熄屏的应用,系统可能将其标记为「活跃后台闲置应用」,直接降低了AlarmManager的触发优先级,导致原有的“永不休眠”设置被覆盖。

可行修复方案

  1. 改用setAlarmClock提升优先级
    相比setExactAndAllowWhileIdle,setAlarmClock拥有系统最高级别的闹钟优先级,系统会确保这类闹钟触发,甚至提前唤醒系统。修改后的核心代码:

    fun setAlarm(timeInMillis: Long) {
        val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val intent = Intent(this, MyAlarm::class.java)
        val pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_MUTABLE)
        
        // 使用setAlarmClock强制系统优先处理
        val alarmClockInfo = AlarmManager.AlarmClockInfo(timeInMillis, null)
        alarmManager.setAlarmClock(alarmClockInfo, pendingIntent)
        
        toastGeneral("Alarm is set")
    }
    

    注:该方法会在系统时钟应用中显示闹钟条目,属于正常系统行为。

  2. 确认并申请精确闹钟权限
    Android 12及以上版本需要SCHEDULE_EXACT_ALARM权限才能使用精确闹钟,先在AndroidManifest.xml中添加:

    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
    

    再在运行时主动请求权限:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
        if (!alarmManager.canScheduleExactAlarms()) {
            startActivity(Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM))
        }
    }
    
  3. 优化PendingIntent唯一性
    原代码中PendingIntent的requestCode固定为0,多次设置闹钟可能导致旧意图被覆盖。建议使用唯一ID生成requestCode:

    val requestCode = timeInMillis.hashCode() // 或自定义唯一标识
    val pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
    
  4. 补充后台保活设置
    除了“永不休眠”,还需检查以下设置:

    • 开启应用的「后台活动」权限:在应用设置的「电池」选项中,确保后台活动处于开启状态;
    • 添加低优先级前台服务:若应用核心依赖闹钟,可启动一个无UI的前台服务,降低被系统杀死的概率。

场景差异解析

  • 熄屏场景:系统进入深度休眠,AlarmManager.RTC_WAKEUP会直接唤醒系统处理广播,此时应用处于「后台休眠」状态,系统会优先响应闹钟触发;
  • 切换后台场景:应用处于「活跃后台」状态,系统会对这类应用进行资源节流,推迟非高优先级任务的执行,直到应用回到前台。通过setAlarmClock提升优先级可绕过该限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:05:19