概述
在移动应用开发中,通知是与用户保持沟通的重要方式。本地通知允许应用在设备上显示消息,即使用户当前没有打开应用。Flutter提供了flutter_local_notifications库来实现跨平台的本地通知功能。
本文将详细介绍本地通知的核心概念、使用方法、高级特性以及在鸿蒙平台上的实现细节。
核心概念
什么是本地通知
本地通知是由应用本地触发的通知,不需要服务器推送。它具有以下特点:
- 离线可用:不需要网络连接
- 即时触发:可以立即显示或定时显示
- 用户交互:支持点击跳转到应用
- 自定义样式:可以自定义标题、内容、图标等
通知的类型
| 类型 | 描述 | 应用场景 |
|---|---|---|
| 即时通知 | 立即显示 | 消息提醒、操作反馈 |
| 定时通知 | 在指定时间显示 | 闹钟、日程提醒 |
| 周期通知 | 按固定间隔重复显示 | 每日提醒、周报推送 |
通知通道(Android)
Android 8.0(API 26)引入了通知通道概念,每个通知必须属于一个通道:
- 重要性级别:决定通知的优先级和显示方式
- 声音设置:自定义通知声音
- 震动模式:自定义震动模式
- 免打扰策略:控制通知在免打扰模式下的行为
基本使用
安装依赖
dependencies:flutter_local_notifications:^17.0.0初始化通知服务
import'package:flutter_local_notifications/flutter_local_notifications.dart';finalFlutterLocalNotificationsPlugin_notificationsPlugin=FlutterLocalNotificationsPlugin();Future<void>initNotifications()async{constAndroidInitializationSettingsinitializationSettingsAndroid=AndroidInitializationSettings('@mipmap/ic_launcher');constInitializationSettingsinitializationSettings=InitializationSettings(android:initializationSettingsAndroid);await_notificationsPlugin.initialize(initializationSettings);}显示简单通知
Future<void>showNotification()async{constAndroidNotificationDetailsandroidDetails=AndroidNotificationDetails('default_channel','默认通知',channelDescription:'应用默认通知通道',importance:Importance.max,priority:Priority.high,);constNotificationDetailsnotificationDetails=NotificationDetails(android:androidDetails);await_notificationsPlugin.show(0,'通知标题','通知内容',notificationDetails,);}核心代码示例
代码示例1:通知服务封装
import'package:flutter_local_notifications/flutter_local_notifications.dart';classNotificationService{staticfinalFlutterLocalNotificationsPlugin_notificationsPlugin=FlutterLocalNotificationsPlugin();staticFuture<void>init()async{constAndroidInitializationSettingsinitializationSettingsAndroid=AndroidInitializationSettings('@mipmap/ic_launcher');constInitializationSettingsinitializationSettings=InitializationSettings(android:initializationSettingsAndroid);await_notificationsPlugin.initialize(initializationSettings);}staticFuture<void>showNotification({required int id,requiredStringtitle,requiredStringbody,String?payload,})async{constAndroidNotificationDetailsandroidDetails=AndroidNotificationDetails('default_channel','默认通知',channelDescription:'应用默认通知通道',importance:Importance.max,priority:Priority.high,ticker:'ticker',);constNotificationDetailsnotificationDetails=NotificationDetails(android:androidDetails);await_notificationsPlugin.show(id,title,body,notificationDetails,payload:payload);}staticFuture<void>scheduleNotification({required int id,requiredStringtitle,requiredStringbody,requiredDateTimescheduledTime,String?payload,})async{constAndroidNotificationDetailsandroidDetails=AndroidNotificationDetails('scheduled_channel','定时通知',channelDescription:'定时任务通知通道',);constNotificationDetailsnotificationDetails=NotificationDetails(android:androidDetails);await_notificationsPlugin.schedule(id,title,body,scheduledTime,notificationDetails,payload:payload,);}staticFuture<void>cancelNotification(int id)async{await_notificationsPlugin.cancel(id);}staticFuture<void>cancelAllNotifications()async{await_notificationsPlugin.cancelAll();}}代码说明:
- 单例模式:使用静态实例避免重复创建
- 初始化配置:配置Android初始化设置
- 即时通知:提供showNotification方法显示即时通知
- 定时通知:提供scheduleNotification方法安排定时通知
- 取消通知:支持取消单个或全部通知
代码示例2:周期通知
classPeriodicNotificationService{staticFuture<void>showPeriodicNotification({required int id,requiredStringtitle,requiredStringbody,RepeatIntervalrepeatInterval=RepeatInterval.hourly,String?payload,})async{constAndroidNotificationDetailsandroidDetails=AndroidNotificationDetails('periodic_channel','周期通知',channelDescription:'周期性通知通道',importance:Importance.defaultImportance,);constNotificationDetailsnotificationDetails=NotificationDetails(android:androidDetails);await_notificationsPlugin.periodicallyShow(id,title,body,repeatInterval,notificationDetails,payload:payload,);}staticFuture<void>showDailyReminder({required int id,requiredStringtitle,requiredStringbody,Timetime,String?payload,})async{constAndroidNotificationDetailsandroidDetails=AndroidNotificationDetails('daily_channel','每日提醒',channelDescription:'每日定时提醒通道',);constNotificationDetailsnotificationDetails=NotificationDetails(android:androidDetails);await_notificationsPlugin.showDailyAtTime(id,title,body,time,notificationDetails,payload:payload,);}}代码说明:
- 周期通知:支持按小时、每日、每周等间隔重复
- 每日提醒:在指定时间每天显示通知
- 灵活配置:支持自定义重复间隔
代码示例3:自定义通知样式
classCustomNotificationService{staticFuture<void>showBigPictureNotification({required int id,requiredStringtitle,requiredStringbody,requiredStringimageUrl,})async{finalBigPictureStyleInformationbigPictureStyle=BigPictureStyleInformation(FilePathAndroidBitmap(imageUrl),largeIcon:FilePathAndroidBitmap(imageUrl),contentTitle:title,summaryText:body,);finalAndroidNotificationDetailsandroidDetails=AndroidNotificationDetails('big_picture_channel','大图通知',channelDescription:'显示大图的通知通道',styleInformation:bigPictureStyle,);finalNotificationDetailsnotificationDetails=NotificationDetails(android:androidDetails);await_notificationsPlugin.show(id,title,body,notificationDetails);}staticFuture<void>showInboxNotification({required int id,requiredStringtitle,requiredList<String>messages,})async{finalInboxStyleInformationinboxStyle=InboxStyleInformation(messages,contentTitle:title,summaryText:'${messages.length}条新消息',);finalAndroidNotificationDetailsandroidDetails=AndroidNotificationDetails('inbox_channel','收件箱通知',channelDescription:'显示多条消息的通知通道',styleInformation:inboxStyle,);finalNotificationDetailsnotificationDetails=NotificationDetails(android:androidDetails);await_notificationsPlugin.show(id,title,'',notificationDetails);}staticFuture<void>showProgressNotification({required int id,requiredStringtitle,int maxProgress=100,int currentProgress=0,})async{finalAndroidNotificationDetailsandroidDetails=AndroidNotificationDetails('progress_channel','进度通知',channelDescription:'显示进度的通知通道',showProgress:true,maxProgress:maxProgress,progress:currentProgress,);finalNotificationDetailsnotificationDetails=NotificationDetails(android:androidDetails);await_notificationsPlugin.show(id,title,'',notificationDetails);}}代码说明:
- 大图通知:显示图片的通知样式
- 收件箱通知:显示多条消息列表
- 进度通知:显示下载或上传进度
代码示例4:通知点击处理
classNotificationHandler{staticFuture<void>init()async{constAndroidInitializationSettingsinitializationSettingsAndroid=AndroidInitializationSettings('@mipmap/ic_launcher');constInitializationSettingsinitializationSettings=InitializationSettings(android:initializationSettingsAndroid);await_notificationsPlugin.initialize(initializationSettings,onDidReceiveNotificationResponse:(response){_handleNotificationTap(response);},);}staticvoid_handleNotificationTap(NotificationResponseresponse){finalpayload=response.payload;if(payload!=null){_navigateToPage(payload);}}staticvoid_navigateToPage(Stringpayload){switch(payload){case'home':break;case'profile':break;case'settings':break;default:break;}}staticFuture<void>checkPendingNotifications()async{finalpendingNotifications=await_notificationsPlugin.pendingNotificationRequests();for(finalnotificationinpendingNotifications){print('Pending notification:${notification.title}');}}}代码说明:
- 点击回调:处理通知点击事件
- Payload传递:通过payload传递页面路由信息
- 页面导航:根据payload跳转到对应页面
- 待处理通知:查询已安排但未显示的通知
高级特性
1. 通知群组
Future<void>createNotificationGroup()async{await_notificationsPlugin.createNotificationChannelGroup(constNotificationChannelGroup('my_group','我的群组',),);}2. 自定义声音
finalAndroidNotificationDetailsandroidDetails=AndroidNotificationDetails('custom_sound_channel','自定义声音',sound:RawResourceAndroidNotificationSound('custom_sound'),);3. 震动模式
finalAndroidNotificationDetailsandroidDetails=AndroidNotificationDetails('vibration_channel','震动通知',vibrationPattern:Int64List.fromList([0,100,500,100]),);4. 通知优先级
finalAndroidNotificationDetailsandroidDetails=AndroidNotificationDetails('priority_channel','高优先级通知',importance:Importance.max,priority:Priority.high,fullScreenIntent:true,);在鸿蒙平台的实现
鸿蒙平台适配
鸿蒙平台对Flutter本地通知的支持与Android类似,因为鸿蒙兼容Android应用。需要注意以下几点:
- 通知权限:需要在鸿蒙平台申请通知权限
- 图标资源:使用合适的图标尺寸
- 通知通道:遵循鸿蒙的通知通道机制
鸿蒙平台权限配置
在module.json5中配置通知权限:
{"module":{"requestPermissions":[{"name":"ohos.permission.NOTIFICATION"}]}}鸿蒙平台注意事项
- 通知样式:鸿蒙平台支持Android的通知样式
- 后台限制:鸿蒙平台对后台通知有一定限制
- 省电模式:省电模式下通知可能延迟
性能对比
| 操作 | 即时通知 | 定时通知 | 周期通知 |
|---|---|---|---|
| 触发延迟 | 立即 | 精确到秒 | 按间隔触发 |
| 资源消耗 | 低 | 中 | 中 |
| 可靠性 | 高 | 高 | 中 |
最佳实践
1. 合理使用通知
避免滥用通知,只在重要事件时发送:
if(isImportantEvent){awaitNotificationService.showNotification(id:1,title:'重要通知',body:'您有一条重要消息',);}2. 统一管理通知ID
使用常量管理通知ID:
classNotificationIds{staticconstint message=1;staticconstint reminder=2;staticconstint update=3;}3. 清理过期通知
及时取消不再需要的通知:
awaitNotificationService.cancelNotification(NotificationIds.reminder);4. 处理点击事件
确保通知点击能正确导航:
onDidReceiveNotificationResponse:(response){if(response.payload=='message'){Navigator.pushNamed(context,'/messages');}}5. 请求通知权限
在发送通知前检查并请求权限:
Future<void>requestNotificationPermission()async{if(!awaitPermission.notification.isGranted){awaitPermission.notification.request();}}常见问题
Q1: 通知不显示怎么办?
A:检查以下几点:
- 是否初始化了通知服务
- 是否创建了通知通道(Android 8.0+)
- 是否授予了通知权限
- 通知ID是否重复
Q2: 如何自定义通知图标?
A:在Android项目的res/mipmap目录添加图标文件,然后在初始化时指定。
Q3: 通知点击后如何传递数据?
A:使用payload参数传递数据,在点击回调中获取。
Q4: 如何取消所有通知?
A:调用cancelAll()方法取消所有通知。
Q5: 定时通知在应用关闭后还会触发吗?
A:会的,定时通知由系统管理,即使应用关闭也会触发。
总结
本地通知是Flutter应用中重要的用户交互方式,通过flutter_local_notifications库可以实现丰富的通知功能。在鸿蒙平台上,本地通知的实现与Android类似,但需要注意权限配置和平台限制。
选择合适的通知类型需要根据业务需求来决定:
| 类型 | 适用场景 | 特点 |
|---|---|---|
| 即时通知 | 消息提醒、操作反馈 | 立即显示,响应快 |
| 定时通知 | 闹钟、日程提醒 | 精确控制时间 |
| 周期通知 | 每日提醒、周报推送 | 自动重复,无需重复配置 |
希望本文能帮助你更好地理解和使用本地通知在Flutter应用中实现消息推送。