flutter本地推送 flutter_local_notifications的使用记录

devtools/2025/2/14 2:56:05/

flutter_local_notifications

效果

安卓配置(AndroidManifest.xml)

    <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

可参考下面

<manifest xmlns:android="http://schemas.android.com/apk/res/android"><uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /><uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /><uses-permission android:name="com.android.alarm.permission.SET_ALARM"/><uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /><uses-permission android:name="android.permission.POST_NOTIFICATIONS"/><applicationandroid:label="whisp"android:name="${applicationName}"android:icon="@mipmap/launcher_icon"><activityandroid:name=".MainActivity"android:exported="true"android:launchMode="singleTop"android:taskAffinity=""android:theme="@style/LaunchTheme"android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"android:hardwareAccelerated="true"android:windowSoftInputMode="adjustResize"><!-- Specifies an Android theme to apply to this Activity as soon asthe Android process has started. This theme is visible to the userwhile the Flutter UI initializes. After that, this theme continuesto determine the Window background behind the Flutter UI. --><meta-dataandroid:name="io.flutter.embedding.android.NormalTheme"android:resource="@style/NormalTheme"/><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity><!-- Don't delete the meta-data below.This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --><meta-dataandroid:name="flutterEmbedding"android:value="2" /></application><!-- Required to query activities that can process text, see:https://developer.android.com/training/package-visibility andhttps://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. --><queries><intent><action android:name="android.intent.action.PROCESS_TEXT"/><data android:mimeType="text/plain"/></intent></queries>
</manifest>

ios配置AppDelegate.swift(参考下面)

import flutter_local_notifications

 FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
        GeneratedPluginRegistrant.register(with: registry)
    }

if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
}

 (参考下面)

import UIKit
import Flutter
import flutter_local_notifications@main
@objc class AppDelegate: FlutterAppDelegate {override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {// This is required to make any communication available in the action isolate.FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) inGeneratedPluginRegistrant.register(with: registry)}if #available(iOS 10.0, *) {UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate}GeneratedPluginRegistrant.register(with: self)return super.application(application, didFinishLaunchingWithOptions: launchOptions)}
}

封装类

import 'dart:async';
import 'dart:io';import 'package:flutter_local_notifications/flutter_local_notifications.dart';@pragma('vm:entry-point')
void notificationTapBackground(NotificationResponse notificationResponse) {// ignore: avoid_printprint('notification(${notificationResponse.id}) action tapped: ''${notificationResponse.actionId} with'' payload: ${notificationResponse.payload}');if (notificationResponse.input?.isNotEmpty ?? false) {// ignore: avoid_printprint('notification action tapped with input: ${notificationResponse.input}');}
}class NotificationHelper {static NotificationHelper? _instance;static NotificationHelper getInstance() {_instance ??= NotificationHelper._initial();return _instance!;}factory NotificationHelper() => _instance ??= NotificationHelper._initial();//创建命名构造函数NotificationHelper._initial() {initialize();}// FlutterLocalNotificationsPlugin实例final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin();final StreamController<NotificationResponse> selectNotificationStream = StreamController<NotificationResponse>.broadcast();// 常量定义static const String _channelId = 'message_notifications';static const String _channelName = 'message notification';static const String _channelDescription = 'Notifications for receiving new messages';static const String _ticker = 'ticker';static const String _darwinNotificationCategoryPlain = 'plainCategory';static const String darwinNotificationCategoryText = 'textCategory';int id = 0;bool _notificationsEnabled = false;// 初始化通知插件Future<void> initialize() async {try {const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/launcher_icon');const DarwinInitializationSettings initializationSettingsIOS =DarwinInitializationSettings(requestSoundPermission: false, requestBadgePermission: false, requestAlertPermission: false);const InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid,iOS: initializationSettingsIOS,);await _notificationsPlugin.initialize(initializationSettings,onDidReceiveNotificationResponse: selectNotificationStream.add,onDidReceiveBackgroundNotificationResponse: notificationTapBackground,);} catch (e) {print('初始化通知插件失败: $e');}}initPermission() {_isAndroidPermissionGranted();_requestPermissions();_configureSelectNotificationSubject();}closeSubject() {selectNotificationStream.close();}Future<void> _isAndroidPermissionGranted() async {if (Platform.isAndroid) {final bool granted =await _notificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.areNotificationsEnabled() ??false;_notificationsEnabled = granted;}}Future<void> _requestPermissions() async {if (Platform.isIOS) {await _notificationsPlugin.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()?.requestPermissions(alert: true,badge: true,sound: true,);} else if (Platform.isAndroid) {final AndroidFlutterLocalNotificationsPlugin? androidImplementation =_notificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>();final bool? grantedNotificationPermission = await androidImplementation?.requestNotificationsPermission();_notificationsEnabled = grantedNotificationPermission ?? false;}}void _configureSelectNotificationSubject() {selectNotificationStream.stream.listen((NotificationResponse? response) async {// await Navigator.of(context).push(MaterialPageRoute<void>(//   builder: (BuildContext context) =>//       SecondPage(response?.payload, data: response?.data),// ));print("点击消息携带的数据$response");});}// 显示通知Future<void> showNotification({required String title, required String body, String payload = ""}) async {const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails(_channelId,_channelName,channelDescription: _channelDescription,importance: Importance.max,priority: Priority.high,ticker: _ticker,);const DarwinNotificationDetails iosNotificationDetails = DarwinNotificationDetails(categoryIdentifier: _darwinNotificationCategoryPlain);const NotificationDetails notificationDetails = NotificationDetails(android: androidNotificationDetails, iOS: iosNotificationDetails);await _notificationsPlugin.show(id++,title,body,notificationDetails,payload: payload,);}/// 取消全部通知cancelAll() {_notificationsPlugin.cancelAll();}/// 取消对应ID的通知cancelId(int id) {_notificationsPlugin.cancel(id);}
}

使用

main方法中初始化

NotificationHelper.getInstance().initialize();

首页中进行权限和方法回调绑定和卸载

首页的instate
NotificationHelper.getInstance().initPermission();

首页的dispose

NotificationHelper.getInstance().closeSubject();

调用提示 接收消息直接调用

NotificationHelper.getInstance().showNotification(title: "科学研究", body: "研究开始了", payload: "payload");

这里可以监控点击推送后动作,如跳转页面  response?.data 是携带的数据

 void _configureSelectNotificationSubject() {selectNotificationStream.stream.listen((NotificationResponse? response) async {// await Navigator.of(context).push(MaterialPageRoute<void>(//   builder: (BuildContext context) =>//       SecondPage(response?.payload, data: response?.data),// ));print("点击消息携带的数据$response");});}


http://www.ppmy.cn/devtools/158653.html

相关文章

android launcher拖动图标释放错位

由于为了设备流畅把所有动画效果设置为0.5&#xff0c;不设置为0是因为锁屏在开机时会有闪黑屏的现象。在此背景下&#xff0c;测试发现在拖动桌面图标时&#xff0c;在图标动画过程中错位时释放图标&#xff0c;则图标会留在错位的位置&#xff0c;不会自动对齐。 原因就是动…

前瞻技术:未来改变生活的关键趋势

人工智能AI&#xff09;在金融投资中越来越重要。它帮助投资者做出更明智的决策&#xff0c;提升决策的科学性。传统的投资方式依赖于个人经验和直觉&#xff0c;这样往往会导致判断失误。AI则通过大量数据分析&#xff0c;提供更准确的信息。 AI使用机器学习算法&#xff0c;…

后端登录校验

登录校验 登录标记&#xff1a; 用户登录成功之后&#xff0c;每一次请求中&#xff0c;都可以获取到该标记&#xff08;会话技术&#xff09; 统一拦截&#xff1a; 过滤器Filter拦截器Interceptor 一、会话技术 会话&#xff1a;用户打开浏览器&#xff0c;访问web服务器…

科技查新过不了怎么办

“科技查新过不了怎么办&#xff1f;” “科技查新不通过的原因是什么&#xff1f;” 想必这些问题一直困扰着各位科研和学术的朋友们&#xff0c;尤其是对于查新经验不够多的小伙伴&#xff0c;在历经千难万险&#xff0c;从选择查新机构、填写线上委托单到付费&#xff0c;…

【机器学习案列】车辆二氧化碳排放量预测

这里是引用 &#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中…

人工智能:所有144本SCI期刊都在这里(20本Top,4本On Hold)

本周投稿推荐 SCI&EI • 4区“水刊”&#xff0c;纯正刊&#xff08;来稿即录&#xff09; • CCF-B类&#xff0c;IEEE一区-Top&#xff08;3天初审&#xff09; EI • 各领域沾边均可&#xff08;2天录用&#xff09; 知网&#xff08;CNKI&#xff09;、谷歌学术 …

使用Python进行数据采集与解析!

包含编程籽料、学习路线图、爬虫代码、安装包等&#xff01;【点击这里】 前言&#xff1a; 在当今大数据时代&#xff0c;数据采集和解析是数据分析和挖掘的重要前提。Python作为一种功能强大且易于学习的编程语言&#xff0c;提供了丰富的库和工具来实现数据采集和解析。本…

vue学习笔记7

打包发布 目标&#xff1a;明确打包的作用 说明&#xff1a;vue脚手架只是开发过程中&#xff0c;协助开发的工具&#xff0c;当真正开发完了 > 脚手架不参与上线 打包的作用&#xff1a; 将多个文件压缩合并成一个文件&#xff0c;语法降级&#xff0c;less sass ts 语法…