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

Android应用关闭且不在最近列表时,如何在指定时间显示通知

方案解答

可以用你已经在使用的AlarmManager实现这个需求,但必须针对Android 9-13的系统限制做适配,同时配合广播接收器和通知组件完成后台提醒。以下是具体的实现要点和替代方案参考:

一、AlarmManager的适配要点

1. 选择合适的闹钟类型与触发方式

  • 必须使用RTC_WAKEUP或ELAPSED_REALTIME_WAKEUP类型,这两种类型能唤醒设备并触发广播,避免设备休眠导致提醒延迟。
  • 不能直接通过AlarmManager启动Activity(Android 9+后台启动限制),而是要通过PendingIntent指向一个自定义BroadcastReceiver,在接收器中发送通知。

2. 突破Doze模式限制

Android 6+的Doze模式会抑制普通闹钟,要保证精准触发,需使用:

  • setExactAndAllowWhileIdle():适合单次精准任务,能在Doze模式下触发,但每15分钟只能调用一次(系统限制)。
  • setAlarmClock():优先级最高,完全不受Doze模式影响,适合需要严格精准时刻的任务提醒,同时系统会在闹钟触发前提前唤醒设备。

3. 权限处理(Android 12+)

  • 在Manifest中声明权限:
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    
  • 运行时请求SCHEDULE_EXACT_ALARM权限:用户拒绝后,只能使用setAndAllowWhileIdle(),但精准度会有所下降。

4. 核心代码示例

设置精准闹钟

val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
    this,
    taskId, // 用唯一的taskId避免PendingIntent被覆盖
    intent,
    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)

// 使用setAlarmClock保证精准触发
val triggerTime = // 你的任务精准触发时间(毫秒级时间戳)
val info = AlarmManager.AlarmClockInfo(triggerTime, pendingIntent)
alarmManager.setAlarmClock(info, pendingIntent)

广播接收器中发送通知

class AlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        context ?: return
        // 构建类似WhatsApp的通知
        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val channelId = "task_reminder_channel"
        
        // Android 8+需要创建通知渠道
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                channelId,
                "任务提醒",
                NotificationManager.IMPORTANCE_HIGH
            ).apply {
                enableVibration(true)
                setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), null)
            }
            notificationManager.createNotificationChannel(channel)
        }
        
        val notification = NotificationCompat.Builder(context, channelId)
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle("任务提醒")
            .setContentText("你的任务该执行了")
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setAutoCancel(true)
            .build()
        
        notificationManager.notify(taskId, notification)
    }
}

二、替代方案:WorkManager

如果遇到部分厂商定制系统对AlarmManager的额外限制,可考虑使用WorkManager:

  • 优势:自动适配系统版本和厂商限制,无需手动处理Doze模式,适合周期性任务。
  • 劣势:精准度不如AlarmManager,OneTimeWorkRequest的最小延迟是10分钟(系统限制),无法做到毫秒级精准触发。因此如果你的需求是必须精准到特定时刻,AlarmManager仍是最优选择。

注意事项

  • 应用被用户强制停止后,所有已设置的Alarm会被系统清除,需要用户重新打开应用才能重新设置。
  • 定期任务需要在每次触发后,重新设置下一次的Alarm,避免遗漏后续提醒。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 11:12:45