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

求助:如何在Flutter中实现带定时提醒与铃声通知的任务功能

Android 平台实现方案

1. 权限配置

在AndroidManifest.xml中添加必需权限:

<!-- 允许设置精确闹钟 -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<!-- 允许发送通知 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- Android 12及以下唤醒设备权限 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />

2. 创建带铃声的通知渠道(Android 8.0+ 强制要求)

在App启动时初始化通知渠道,确保通知能播放铃声:

private fun initReminderChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val channelId = "daily_task_reminder"
        val channelName = "日常任务提醒"
        val channelDesc = "定时推送任务提醒,附带铃声"
        val importance = NotificationManager.IMPORTANCE_HIGH // 高优先级保证铃声正常播放
        
        val channel = NotificationChannel(channelId, channelName, importance).apply {
            description = channelDesc
            // 设置系统默认通知铃声,也可替换为自定义铃声路径
            setSound(
                RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
                AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()
            )
            enableVibration(true)
        }
        
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

3. 调度精确闹钟

使用AlarmManager设置定时触发事件,确保到点唤醒设备并发送通知:

fun setExactTaskReminder(targetTimeMillis: Long, taskTitle: String, taskContent: String) {
    val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
    val intent = Intent(this, ReminderReceiver::class.java).apply {
        putExtra("title", taskTitle)
        putExtra("content", taskContent)
    }
    
    val pendingIntent = PendingIntent.getBroadcast(
        this,
        taskTitle.hashCode(), // 用任务标题哈希值做唯一请求码,避免重复覆盖
        intent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )
    
    // Android 12+ 需检查精确闹钟权限
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        if (alarmManager.canScheduleExactAlarms()) {
            alarmManager.setExactAndAllowWhileIdle(
                AlarmManager.RTC_WAKEUP,
                targetTimeMillis,
                pendingIntent
            )
        } else {
            // 引导用户开启权限
            startActivity(Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM))
        }
    } else {
        alarmManager.setExactAndAllowWhileIdle(
            AlarmManager.RTC_WAKEUP,
            targetTimeMillis,
            pendingIntent
        )
    }
}

4. 实现广播接收器发送通知

创建ReminderReceiver类,接收闹钟触发信号并弹出通知:

class ReminderReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        context ?: return
        val title = intent?.getStringExtra("title") ?: "任务提醒"
        val content = intent?.getStringExtra("content") ?: "该完成你的日常任务了"
        
        val channelId = "daily_task_reminder"
        val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)
        val pendingIntent = PendingIntent.getActivity(
            context,
            0,
            launchIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
        
        val notification = NotificationCompat.Builder(context, channelId)
            .setSmallIcon(R.drawable.ic_reminder) // 替换为你的通知图标
            .setContentTitle(title)
            .setContentText(content)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .build()
        
        NotificationManagerCompat.from(context).notify(title.hashCode(), notification)
    }
}

iOS 平台实现方案

1. 权限配置

在Info.plist中添加权限说明:

<key>NSNotificationSettingsUsageDescription</key>
<string>需要发送通知提醒您完成日常任务</string>

2. 请求通知权限

在App启动时向用户申请通知权限:

import UserNotifications

func requestNotificationAuth() {
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
        if granted {
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }
}

3. 创建定时通知请求

使用UNUserNotificationCenter设置定时提醒:

func setTaskReminder(targetDate: Date, taskTitle: String, taskContent: String) {
    let content = UNMutableNotificationContent()
    content.title = taskTitle
    content.body = taskContent
    // 使用系统默认铃声,自定义铃声需将音频文件加入项目并指定文件名
    content.sound = .default
    
    // 构建日期触发器
    let dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: targetDate)
    let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
    
    // 创建唯一通知请求ID
    let requestId = "task_reminder_\(UUID().uuidString)"
    let request = UNNotificationRequest(identifier: requestId, content: content, trigger: trigger)
    
    // 添加到通知中心
    UNUserNotificationCenter.current().add(request) { error in
        if let error = error {
            print("添加提醒失败:\(error.localizedDescription)")
        }
    }
}

4. 处理通知点击(可选)

实现UNUserNotificationCenterDelegate处理用户点击通知的行为:

extension AppDelegate: UNUserNotificationCenterDelegate {
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        // 跳转到对应任务页面或执行其他逻辑
        let requestId = response.notification.request.identifier
        print("用户点击了提醒:\(requestId)")
        
        completionHandler()
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:35:39