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

如何在Flutter中实现本地价格预警通知功能

基于价格的本地预警功能实现方案

核心逻辑梳理

  • 存储用户目标金额:用本地数据库(如iOS的Core Data、Android的Room)保存用户设置的目标金额及对应监控标的信息。
  • 定期拉取API数据:无论应用处于前台还是后台,定时请求价格接口,对比实际金额与目标金额。
  • 触发通知:当实际金额等于目标金额时,立即推送本地通知。
  • 权限前置:必须先获取用户的通知权限,否则无法推送通知。

iOS平台实现步骤

1. 申请通知权限

App启动时发起权限请求,代码示例:

import UserNotifications

func requestNotificationPermission() {
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
        if let error = error {
            print("通知权限申请失败:\(error.localizedDescription)")
        }
    }
}

2. 后台任务配置

  • 在Info.plist中添加UIBackgroundModes,勾选fetch(后台数据获取)或processing(后台任务处理)。
  • 配置后台刷新任务定期拉取API:
func setupBackgroundFetch() {
    UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplication.backgroundFetchIntervalMinimum)
}

// 实现AppDelegate的后台刷新回调
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    fetchPriceDataFromAPI { [weak self] price in
        guard let self = self, let targetPrice = self.getTargetPriceFromLocalStorage() else {
            completionHandler(.failed)
            return
        }
        if price == targetPrice {
            self.sendLocalNotification(title: "价格预警", body: "目标金额已达成!")
        }
        completionHandler(.newData)
    }
}

3. 推送本地通知

func sendLocalNotification(title: String, body: String) {
    let content = UNMutableNotificationContent()
    content.title = title
    content.body = body
    content.sound = .default
    
    let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil)
    UNUserNotificationCenter.current().add(request) { error in
        if let error = error {
            print("推送通知失败:\(error.localizedDescription)")
        }
    }
}

4. 前台显示通知

默认iOS前台不弹出通知,需实现UNUserNotificationCenterDelegate方法开启前台通知:

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    completionHandler([.alert, .sound])
}

Android平台实现步骤

1. 申请通知权限

  • Android 13及以上需在Manifest中添加权限:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
  • 动态申请权限:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1001)
}

2. 后台任务配置

用WorkManager实现定时拉取,保证后台可执行:

class PriceCheckWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
    override suspend fun doWork(): Result {
        val price = fetchPriceFromAPI()
        val targetPrice = getTargetPriceFromRoom()
        
        if (price == targetPrice) {
            sendLocalNotification(applicationContext, "价格预警", "目标金额已达成!")
        }
        
        // 配置每15分钟重复执行
        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
        
        val request = PeriodicWorkRequestBuilder<PriceCheckWorker>(15, TimeUnit.MINUTES)
            .setConstraints(constraints)
            .build()
        
        WorkManager.getInstance(applicationContext).enqueue(request)
        
        return Result.success()
    }
}
  • 启动Worker:
val request = PeriodicWorkRequestBuilder<PriceCheckWorker>(15, TimeUnit.MINUTES)
    .setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build())
    .build()
WorkManager.getInstance(this).enqueue(request)

3. 推送本地通知

fun sendLocalNotification(context: Context, title: String, body: String) {
    val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    
    // Android 8.0+需创建通知渠道
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val channel = NotificationChannel("price_alert_channel", "价格预警", NotificationManager.IMPORTANCE_DEFAULT)
        notificationManager.createNotificationChannel(channel)
    }
    
    val intent = context.packageManager.getLaunchIntentForPackage(context.packageName)
    val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
    
    val notification = NotificationCompat.Builder(context, "price_alert_channel")
        .setContentTitle(title)
        .setContentText(body)
        .setSmallIcon(R.drawable.ic_notification)
        .setContentIntent(pendingIntent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .build()
    
    notificationManager.notify(1, notification)
}

4. 前台通知处理

Android前台默认会显示通知,权限正常即可生效,无需额外配置。

注意事项

  • API请求频率:建议设置15分钟以上间隔,避免系统限制或过度耗电。
  • 异常处理:拉取API时需处理网络异常,可添加重试或缓存策略。
  • 多标的支持:数据库设计要兼容多用户、多监控标的的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 21:07:17