Flutter通知管理插件notifications_utils的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter通知管理插件notifications_utils的使用

notifications_utils 是一个 Flutter 插件,用于从通知中心获取已发送的通知,并在 Android、iOS 和 MacOS 上取消这些通知。在 iOS 和 MacOS 上使用 UNUserNotificationCenter,在 Android 上使用 NotificationManager

使用方法

获取通知

List<DeliveredNotification?> notifications = await NotificationsUtils().getDeliveredNotifications();
// `whereType` 用于过滤掉非空的通知。
// 这是因为 `pigeon` 包不支持非空泛型类型。
for (final notification in notifications.whereType<DeliveredNotification>()) {
  print(
    "id: ${notification.id}\n"
    "threadIdentifier: ${notification.threadIdentifier}\n"
    "title: ${notification.title}\n"
    "body: ${notification.body}\n"
    "payload map: ${notification.payload}\n"
    "androidTag: ${notification.androidTag}\n",
  );
}

取消已发送的通知

// 在 Android 上,通知 ID 是整数,在 iOS 上是字符串。
// 因此使用 `NotificationId` 类。
final NotificationId notificationId = NotificationId(
  /*optional*/ androidId: 1,
  /*optional*/ iosId: "someId",
  /*optional*/ androidTag: "someTag",
);
NotificationsUtils().removeDeliveredNotifications([notificationId]);

为什么存在这个插件?

是的,已经有一些优秀的通知包,例如:

但是:

  • awesome_notifications 包不支持取消已发送的通知。
  • flutter_local_notifications 包只能取消由其创建的通知。

示例代码

以下是一个完整的示例代码,展示了如何使用 notifications_utils 插件:

import 'dart:math';
import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:notifications_utils/notifications_utils.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  var _notifications = <DeliveredNotification>[];
  final _notificationsPlugin = FlutterLocalNotificationsPlugin();

  [@override](/user/override)
  void initState() {
    super.initState();
    _initAndGet();
  }

  Future<void> _initAndGet() async {
    await _notificationsPlugin.initialize(
      const InitializationSettings(
        iOS: DarwinInitializationSettings(),
        macOS: DarwinInitializationSettings(),
        android: AndroidInitializationSettings('@mipmap/ic_launcher'),
      ),
    );
    _notificationsPlugin
        .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
        ?.requestPermission();
    await _getNotifications();
  }

  Future<void> _getNotifications() async {
    try {
      final notifications = await NotificationsUtils().getDeliveredNotifications();
      _notifications = notifications.whereType<DeliveredNotification>().toList();
      if (mounted) setState(() {});
    } catch (e, st) {
      debugPrintStack(stackTrace: st, label: e.toString());
    }
  }

  void _removeNotification(NotificationId notificationId) {
    NotificationsUtils().removeDeliveredNotifications([notificationId]);
    _getNotifications();
  }

  Future<void> _showNotification() async {
    final darwinNotificationDetails = DarwinNotificationDetails(
      subtitle: generateWordPairs().take(3).join(' '),
      threadIdentifier: generateWordPairs().take(1).join(' '),
    );
    await _notificationsPlugin.show(
      Random().nextInt(10000000),
      generateWordPairs().take(3).join(' '),
      generateWordPairs().take(3).join(' '),
      NotificationDetails(
        android: const AndroidNotificationDetails('channel id', 'channel name'),
        iOS: darwinNotificationDetails,
        macOS: darwinNotificationDetails,
      ),
      payload: generateWordPairs().take(3).join(' '),
    );
    _getNotifications();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Notifications utils example'),
        ),
        floatingActionButton: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            FloatingActionButton(
              onPressed: () => _showNotification(),
              child: const Icon(Icons.add),
            ),
            const SizedBox(height: 10),
            FloatingActionButton(
              onPressed: () => _getNotifications(),
              child: const Icon(Icons.refresh),
            ),
          ],
        ),
        body: ListView(
          children: [
            if (_notifications.isEmpty)
              const ListTile(
                title: Text('No delivered notifications'),
              ),
            for (final notification in _notifications)
              ListTile(
                onTap: () => _removeNotification(notification.id),
                leading: Text('Id:\n${notification.id.id}'),
                trailing: Text('Thread id:\n${notification.threadIdentifier}'),
                title: Text(
                    'Title: ${notification.title}. Subtitle: ${notification.subtitle}'),
                subtitle: Text(
                    'Body: ${notification.body}\nPayload: ${notification.payload}'),
              ),
          ],
        ),
      ),
    );
  }
}

extension on NotificationId {
  String get id => androidId?.toString() ?? iosId ?? 'null';
}

更多关于Flutter通知管理插件notifications_utils的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter通知管理插件notifications_utils的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用notifications_utils插件来管理通知的示例代码。notifications_utils是一个强大的Flutter插件,它提供了创建、更新、删除本地和远程通知的功能。请注意,具体功能可能会根据插件的版本有所不同,因此请参考插件的官方文档获取最新信息。

首先,确保你已经在pubspec.yaml文件中添加了notifications_utils依赖:

dependencies:
  flutter:
    sdk: flutter
  notifications_utils: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

接下来,我们编写一些示例代码来展示如何使用notifications_utils插件。

初始化插件

在你的Flutter应用的入口文件(通常是main.dart)中初始化插件:

import 'package:flutter/material.dart';
import 'package:notifications_utils/notifications_utils.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  NotificationsUtils.init();  // 初始化插件
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

创建通知

在应用的某个地方(例如一个按钮点击事件中)创建一个通知:

import 'package:flutter/material.dart';
import 'package:notifications_utils/notifications_utils.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {

  void showNotification() {
    var androidPlatformChannelSpecifics = AndroidNotificationDetails(
      'your_channel_id',
      'Your Channel Name',
      'Your Channel Description',
      importance: Importance.Max,
      priority: Priority.High,
      enableLights: true,
      lightColor: Colors.blue,
      enableVibration: true,
      playSound: true,
      sound: RawResourceAndroidNotificationSound('your_sound_file'),
      channelShowBadge: true,
    );

    var iOSPlatformChannelSpecifics = IOSNotificationDetails();

    var platformChannelSpecifics = NotificationDetails(
      android: androidPlatformChannelSpecifics,
      iOS: iOSPlatformChannelSpecifics
    );

    var notification = FlutterLocalNotificationsPlugin()
        .show(
          0,
          'Hello, World!',
          'This is a local notification!',
          platformChannelSpecifics,
          payload: 'item x',
        );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Notifications Utils Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: showNotification,
          child: Text('Show Notification'),
        ),
      ),
    );
  }
}

处理通知点击事件

你可能还想处理用户点击通知时的事件。为此,你可以使用FlutterLocalNotificationsPluginsetNotificationOpenedHandler方法:

import 'package:flutter_local_notifications/flutter_local_notifications.dart';

// 在你的_HomeScreenState类中,添加以下代码

@override
void initState() {
  super.initState();

  var initializationSettings = InitializationSettings(
    android: AndroidInitializationSettings('@mipmap/ic_launcher'),
    iOS: IOSInitializationSettings(
      requestAlertPermission: true,
      requestBadgePermission: true,
      requestSoundPermission: true,
    ),
  );

  FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  flutterLocalNotificationsPlugin.initialize(initializationSettings,
      onSelectNotification: onSelectNotification);
}

void onSelectNotification(String payload) {
  // 处理点击事件,例如显示一个对话框
  showDialog(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        title: Text('Payload'),
        content: Text('$payload'),
        actions: <Widget>[
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: Text('OK'),
          ),
        ],
      );
    },
  );
}

完整代码示例

将上述所有代码片段整合到一个完整的Flutter应用中:

import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:notifications_utils/notifications_utils.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  NotificationsUtils.init();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {

  FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  @override
  void initState() {
    super.initState();

    var initializationSettings = InitializationSettings(
      android: AndroidInitializationSettings('@mipmap/ic_launcher'),
      iOS: IOSInitializationSettings(
        requestAlertPermission: true,
        requestBadgePermission: true,
        requestSoundPermission: true,
      ),
    );

    flutterLocalNotificationsPlugin.initialize(initializationSettings,
        onSelectNotification: onSelectNotification);
  }

  void showNotification() {
    var androidPlatformChannelSpecifics = AndroidNotificationDetails(
      'your_channel_id',
      'Your Channel Name',
      'Your Channel Description',
      importance: Importance.Max,
      priority: Priority.High,
      enableLights: true,
      lightColor: Colors.blue,
      enableVibration: true,
      playSound: true,
      sound: RawResourceAndroidNotificationSound('your_sound_file'),
      channelShowBadge: true,
    );

    var iOSPlatformChannelSpecifics = IOSNotificationDetails();

    var platformChannelSpecifics = NotificationDetails(
      android: androidPlatformChannelSpecifics,
      iOS: iOSPlatformChannelSpecifics
    );

    flutterLocalNotificationsPlugin.show(
      0,
      'Hello, World!',
      'This is a local notification!',
      platformChannelSpecifics,
      payload: 'item x',
    );
  }

  void onSelectNotification(String payload) {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Payload'),
          content: Text('$payload'),
          actions: <Widget>[
            TextButton(
              onPressed: () => Navigator.of(context).pop(),
              child: Text('OK'),
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Notifications Utils Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: showNotification,
          child: Text('Show Notification'),
        ),
      ),
    );
  }
}

请确保替换your_channel_idyour_sound_file为实际的通道ID和声音文件资源名。此外,确保Android的mipmap文件夹中有相应的图标文件。

这段代码展示了如何使用notifications_utils插件来创建和管理本地通知,并处理通知点击事件。如果你需要处理远程通知(例如来自服务器的推送通知),你将需要配置Firebase Cloud Messaging(FCM)或其他推送通知服务。

回到顶部