为啥 0 个待处理通知
Posted
技术标签:
【中文标题】为啥 0 个待处理通知【英文标题】:Why 0 pending notifications为什么 0 个待处理通知 【发布时间】:2021-08-11 17:18:57 【问题描述】:我正在使用flutter_local_notification V 5.00+3 并调用flutterLocalNotificationsPlugin.pendingNotificationRequests()
总是返回 0(零),即使我执行
FlutterLocalNotificationsPlugin().show
两次不点击通知,离开通知,代码如下,摘自示例,简单修改添加idOfMsg作为消息的id。
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';
import 'package:device_info/device_info.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
import 'package:rxdart/subjects.dart';
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
/// Streams are created so that app can respond to notification-related events
/// since the plugin is initialised in the `main` function
final BehaviorSubject<ReceivedNotification> didReceiveLocalNotificationSubject =
BehaviorSubject<ReceivedNotification>();
final BehaviorSubject<String?> selectNotificationSubject =
BehaviorSubject<String?>();
const MethodChannel platform =
MethodChannel('dexterx.dev/flutter_local_notifications_example');
class ReceivedNotification
ReceivedNotification(
required this.id,
required this.title,
required this.body,
required this.payload,
);
final int id;
final String? title;
final String? body;
final String? payload;
String? selectedNotificationPayload;
/// IMPORTANT: running the following code on its own won't work as there is
/// setup required for each platform head project.
///
/// Please download the complete example app from the GitHub repository where
/// all the setup has been done
Future<void> main() async
// needed if you intend to initialize in the `main` function
WidgetsFlutterBinding.ensureInitialized();
final NotificationAppLaunchDetails? notificationAppLaunchDetails =
await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
String initialRoute = HomePage.routeName;
if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false)
selectedNotificationPayload = notificationAppLaunchDetails!.payload;
initialRoute = SecondPage.routeName;
const androidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
/// Note: permissions aren't requested here just to demonstrate that can be
/// done later
final iosInitializationSettings initializationSettingsIOS =
IOSInitializationSettings(
requestAlertPermission: false,
requestBadgePermission: false,
requestSoundPermission: false,
onDidReceiveLocalNotification:
(int id, String? title, String? body, String? payload) async
didReceiveLocalNotificationSubject.add(ReceivedNotification(
id: id, title: title, body: body, payload: payload));
);
const MacOSInitializationSettings initializationSettingsMacOS =
MacOSInitializationSettings(
requestAlertPermission: false,
requestBadgePermission: false,
requestSoundPermission: false);
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: initializationSettingsMacOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: (String? payload) async
if (payload != null)
debugPrint('notification payload: $payload');
selectedNotificationPayload = payload;
selectNotificationSubject.add(payload);
);
runApp(
MaterialApp(
initialRoute: initialRoute,
routes: <String, WidgetBuilder>
HomePage.routeName: (_) => HomePage(notificationAppLaunchDetails),
SecondPage.routeName: (_) => SecondPage(selectedNotificationPayload)
,
),
);
class PaddedElevatedButton extends StatelessWidget
const PaddedElevatedButton(
required this.buttonText,
required this.onPressed,
Key? key,
) : super(key: key);
final String buttonText;
final VoidCallback onPressed;
@override
Widget build(BuildContext context) => Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 8),
child: ElevatedButton(
onPressed: onPressed,
child: Text(buttonText),
),
);
class HomePage extends StatefulWidget
const HomePage(
this.notificationAppLaunchDetails,
Key? key,
) : super(key: key);
static const String routeName = '/';
final NotificationAppLaunchDetails? notificationAppLaunchDetails;
bool get didNotificationLaunchApp =>
notificationAppLaunchDetails?.didNotificationLaunchApp ?? false;
@override
_HomePageState createState() => _HomePageState();
class _HomePageState extends State<HomePage>
@override
void initState()
super.initState();
_requestPermissions();
_configureDidReceiveLocalNotificationSubject();
_configureSelectNotificationSubject();
void _configureSelectNotificationSubject()
selectNotificationSubject.stream.listen((String? payload) async
await Navigator.pushNamed(context, '/secondPage');
);
void _requestPermissions()
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true,
badge: true,
sound: true,
);
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
MacOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true,
badge: true,
sound: true,
);
void _configureDidReceiveLocalNotificationSubject()
didReceiveLocalNotificationSubject.stream
.listen((ReceivedNotification receivedNotification) async
await showDialog(
context: context,
builder: (BuildContext context) => CupertinoAlertDialog(
title: receivedNotification.title != null
? Text(receivedNotification.title!)
: null,
content: receivedNotification.body != null
? Text(receivedNotification.body!)
: null,
actions: <Widget>[
CupertinoDialogAction(
isDefaultAction: true,
onPressed: () async
Navigator.of(context, rootNavigator: true).pop();
await Navigator.push(
context,
MaterialPageRoute<void>(
builder: (BuildContext context) =>
SecondPage(receivedNotification.payload),
),
);
,
child: const Text('Ok'),
)
],
),
);
);
@override
void dispose()
didReceiveLocalNotificationSubject.close();
selectNotificationSubject.close();
super.dispose();
@override
Widget build(BuildContext context) => MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8),
child: Center(
child: Column(
children: <Widget>[
const Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 8),
child: Text(
'Tap on a notification when it appears to trigger'
' navigation'),
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 8),
child: Text.rich(
TextSpan(
children: <InlineSpan>[
const TextSpan(
text: 'Did notification launch app? ',
style: TextStyle(fontWeight: FontWeight.bold),
),
TextSpan(
text: '$widget.didNotificationLaunchApp',
)
],
),
),
),
if (widget.didNotificationLaunchApp)
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 8),
child: Text.rich(
TextSpan(
children: <InlineSpan>[
const TextSpan(
text: 'Launch notification payload: ',
style: TextStyle(fontWeight: FontWeight.bold),
),
TextSpan(
text: widget
.notificationAppLaunchDetails!.payload,
)
],
),
),
),
PaddedElevatedButton(
buttonText: 'Show 1 plain notification with payload',
onPressed: () async
await _showNotification(1);
,
),
PaddedElevatedButton(
buttonText: 'Show 2 plain notification with payload',
onPressed: () async
await _showNotification(2);
,
),
PaddedElevatedButton(
buttonText: 'Check pending notifications',
onPressed: () async
await _checkPendingNotificationRequests();
,
),
],
),
),
),
),
),
);
Future<void> _showNotification(int idOfMsg) async
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'your channel id', 'your channel name', 'your channel description',
importance: Importance.max,
priority: Priority.high,
ticker: 'ticker');
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
idOfMsg, 'plain title'+ idOfMsg.toString(), 'plain body', platformChannelSpecifics,
payload: 'item x' + idOfMsg.toString());
Future<void> _cancelNotification() async
await flutterLocalNotificationsPlugin.cancel(0);
Future<void> _checkPendingNotificationRequests() async
final List<PendingNotificationRequest> pendingNotificationRequests =
await flutterLocalNotificationsPlugin.pendingNotificationRequests();
return showDialog<void>(
context: context,
builder: (BuildContext context) => AlertDialog(
content:
Text('$pendingNotificationRequests.length pending notification '
'requests'),
actions: <Widget>[
TextButton(
onPressed: ()
Navigator.of(context).pop();
,
child: const Text('OK'),
),
],
),
);
Future<void> _cancelAllNotifications() async
await flutterLocalNotificationsPlugin.cancelAll();
class SecondPage extends StatefulWidget
const SecondPage(
this.payload,
Key? key,
) : super(key: key);
static const String routeName = '/secondPage';
final String? payload;
@override
State<StatefulWidget> createState() => SecondPageState();
class SecondPageState extends State<SecondPage>
String? _payload;
@override
void initState()
super.initState();
_payload = widget.payload;
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text('Second Screen $_payload ?? '' with payload: '),
),
body: Center(
child: ElevatedButton(
onPressed: ()
Navigator.pop(context);
,
child: const Text('Go back!'),
),
),
);
请帮忙,以便我可以获取用户仍未点击或取消的通知列表。
【问题讨论】:
【参考方案1】:pendingNotificationRequests 用于尚未出现在通知面板中的预定通知。
getActiveNotifications 用于通知面板中可用的通知。
【讨论】:
【参考方案2】:我找到了示例中的解决方案
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()!
.getActiveNotifications();
【讨论】:
以上是关于为啥 0 个待处理通知的主要内容,如果未能解决你的问题,请参考以下文章
立即在 WooCommerce 中设置待处理订单并发送处理电子邮件通知