求助:如何在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
相关产品推荐
相关产品推荐

