flutter本地推送 flutter_local_notifications的使用记录

news2025/2/23 17:06:57

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"/>
    <application
        android:label="whisp"
        android:name="${applicationName}"
        android:icon="@mipmap/launcher_icon">
        <activity
            android: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 as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android: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-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
    <!-- Required to query activities that can process text, see:
         https://developer.android.com/training/package-visibility and
         https://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) in
        GeneratedPluginRegistrant.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_print
  print('notification(${notificationResponse.id}) action tapped: '
      '${notificationResponse.actionId} with'
      ' payload: ${notificationResponse.payload}');
  if (notificationResponse.input?.isNotEmpty ?? false) {
    // ignore: avoid_print
    print('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.coloradmin.cn/o/2299197.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Springboot 中如何使用Sentinel

在 Spring Boot 中使用 Sentinel 非常方便&#xff0c;Spring Cloud Alibaba 提供了 spring-cloud-starter-alibaba-sentinel 组件&#xff0c;可以快速将 Sentinel 集成到你的 Spring Boot 应用中&#xff0c;并利用其强大的流量控制和容错能力。 下面是一个详细的步骤指南 …

一个让Stable Diffusion更稳定、更易用的Github开源项目

2023除了ChatGPT大火&#xff0c;Stable Diffusion同样也是非常火热&#xff0c;Stable Diffusion是一个Github开源项目&#xff0c;很多爱好者都会本地安装&#xff0c;但面对一些初学者来说&#xff0c;在安装、配置和使用过程中还是会经常出现很多问题&#xff0c;特别不了解…

Docker+Jenkins自动化部署SpringBoot项目【详解git,jdk,maven,ssh配置等各种配置,附有示例+代码】

文章目录 DockerJenkins部署SpringBoot项目一.准备工作1.1安装jdk111.2安装Maven 二.Docker安装Jenkins2.1安装Docker2.2 安装Jenkins2.3进入jenkins 三.Jenkins设置3.1安装jenkins插件3.2全局工具配置全局配置jdk全局配置maven全局配置git 3.3 系统配置安装 Publish Over SSH …

.NET SixLabors.ImageSharp v1.0 图像实用程序控制台示例

使用 C# 控制台应用程序示例在 Windows、Linux 和 MacOS 机器上处理图像&#xff0c;包括创建散点图和直方图&#xff0c;以及根据需要旋转图像以便正确显示。 这个小型实用程序库需要将 NuGet SixLabors.ImageSharp包&#xff08;版本 1.0.4&#xff09;添加到.NET Core 3.1/ …

soular基础教程-使用指南

soular是TikLab DevOps工具链的统一帐号中心&#xff0c;今天来介绍如何使用 soular 配置你的组织、工作台&#xff0c;快速入门上手。 &#xfeff; 1. 账号管理 可以对账号信息进行多方面管理&#xff0c;包括分配不同的部门、用户组等&#xff0c;从而确保账号权限和职责…

《Spring实战》(第6版)第1章 Spring起步

第1部分 Spring基础 第1章 Spring起步 1.1 什么是Spring Spring的核心是提供一个容器(container)。 称为Spring应用上下文(Spring application context)。 创建和管理应用的组件(bean)&#xff0c;与上下文装配在一起。 Bean装配通过依赖注入(Dependency Injection,DI)。…

PAT乙级真题 — 1084 外观数列(java)

外观数列是指具有以下特点的整数序列&#xff1a; d, d1, d111, d113, d11231, d112213111, ...它从不等于 1 的数字 d 开始&#xff0c;序列的第 n1 项是对第 n 项的描述。比如第 2 项表示第 1 项有 1 个 d&#xff0c;所以就是 d1&#xff1b;第 2 项是 1 个 d&#xff08;对…

I.MX6ull 看门狗

一、看门狗介绍 WatchDog是为了能够防止程序跑飞而使用的一种硬件模块。如果你的程序没有跑飞&#xff0c;那么你的程序会 定时的去喂看门狗&#xff1b;如果你的程序跑飞了,那么就不会再去喂狗了&#xff0c;如果超过了喂狗的时间&#xff0c;那么狗就会 自己生成一个信号来重…

鲸鱼算法优化Transformer+KAN网络并应用于时序预测任务

&#x1f60a;&#x1f60a;&#x1f60a;欢迎来到本博客&#x1f60a;&#x1f60a;&#x1f60a; 本次博客内容将聚焦于深度学习的相关知识与实践 &#x1f389;作者简介&#xff1a;⭐️⭐️⭐️主要研究方向涵盖深度学习、计算机视觉等方向。 &#x1f4dd;目前更新&#x…

一维差分算法篇:高效处理区间加减

那么在正式介绍我们的一维差分的原理前&#xff0c;我们先来看一下一维差分所应用的一个场景&#xff0c;那么假设我们现在有一个区间为[L,R]的一个数组&#xff0c;那么我要在这个数组中的某个子区间比如[i,m] (L<i<m<R)进行一个加k值或者减去k值的一个操作&#xff…

【C++】基础入门(详解)

&#x1f31f; Hello&#xff0c;我是egoist2023&#xff01; &#x1f30d; 种一棵树最好是十年前&#xff0c;其次是现在&#xff01; 目录 输入&输出 缺省参数(默认参数) 函数重载 引用 概念及定义 特性及使用 const引用 与指针的关系 内联inline和nullptr in…

【快速入门】Unity 常用组件(功能块)

欢迎关注 、订阅专栏 【unity 新手教程】谢谢你的支持&#xff01;&#x1f49c;&#x1f49c; 文章目录 Unity 常用组件&#xff08;功能块&#xff09;&#xff1a;Transform - 变换&#xff1a;坐标、朝向、大小Mesh Filter - 加载网格数据Mesh Renderer- 渲染网格Camera - …

Nessus 工具使用全攻略

目录 一、Nessus&#xff1a;网络安全的坚固防线 二、Nessus 安装指南 &#xff08;一&#xff09;获取安装包 &#xff08;二&#xff09;安装流程 三、初次配置&#xff1a;开启 Nessus 的第一步 &#xff08;一&#xff09;账号注册 &#xff08;二&#xff09;激活 …

PHP代驾系统小程序

&#x1f697; 代驾系统 —— 安全、便捷、智能的出行新选择 &#x1f527; 一款基于先进ThinkPHPUniapp技术架构&#xff0c;匠心独运的代驾软件横空出世&#xff0c;微信小程序端率先登场&#xff0c;为您的出行之旅增添前所未有的便捷与安全。它不仅是您贴心的出行助手&…

网络安全扫描--基础篇

前言 1、了解互联网安全领域中日趋重要的扫描技术 2、了解在不同网络场景下扫描技术手段 3、熟悉linux下系统内核防护策略并能大件一个有效的系统防护体系 4、增强工作安全意识&#xff0c;并能有效的实践于工作场景中 目录 1、熟悉主机扫描工具&#xff08;fping&#xff0c;…

【MySQL数据库】Ubuntu下的mysql

目录 1&#xff0c;安装mysql数据库 2&#xff0c;mysql默认安装路径 3&#xff0c;my.cnf配置文件? 4&#xff0c;mysql运用的相关指令及说明 5&#xff0c;数据库、表的备份和恢复 mysql是一套给我们提供数据存取的&#xff0c;更加有利于管理数据的服务的网络程序。下…

WebRTC与EasyRTC:开启智能硬件音视频通讯的全新旅程

在当今数字化时代&#xff0c;音视频通讯技术正以前所未有的速度革新着我们的生活与工作方式。WebRTC与EasyRTC作为这一领域的佼佼者&#xff0c;正携手为智能硬件的音视频通讯注入强大动力&#xff0c;开启全新的篇章。 一、WebRTC与智能硬件融合的崭新趋势 WebRTC技术&…

基于Ceedling的嵌入式软件单元测试

Ceedling 如果你使用 Ceedling&#xff08;一个针对 C 代码单元测试的构建管理器&#xff09;&#xff0c;可以更方便地管理测试。Ceedling 会自动处理 Unity 和 CMock 的集成&#xff0c;无需手动编写 Makefile。 1.环境搭建 1.1 Ruby环境 sudo apt-get install ruby1.2 安…

一文深入了解DeepSeek-R1:模型架构

本文深入探讨了 DeepSeek-R1 模型架构。让我们从输入到输出追踪 DeepSeek-R1 模型&#xff0c;以找到架构中的新发展和关键部分。DeepSeek-R1 基于 DeepSeek-V3-Base 模型架构。本文旨在涵盖其设计的所有重要方面。 &#x1f4dd; 1. 输入上下文长度 DeepSeek-R1的输入上下文长…

2024年终总结和2025年规划

2024年的主线是AI基础的学习和读书&#xff0c;虽然AI学习花费了更多的时间&#xff0c;但是读书长久看来于我是更重要的事情&#xff0c;哈哈哈&#xff0c;因此先简单回顾一下读书记忆&#xff0c;回顾我的2024&#xff0c;再展望一下我的2025. 我的2024年记忆 读万卷书&am…