I am using flutter_local_notification
and workmanager
plugins in order to run some background code when a notification is generated (only Android). This is how flutter_local_notification is initialised:
final StreamController<ReceivedNotification> didReceiveLocalNotificationSubject = StreamController<ReceivedNotification>.broadcast();
Future<void> init() async {
await _configureLocalTimeZone();
notificationAppLaunchDetails = await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
if (notificationAppLaunchDetails!.didNotificationLaunchApp) {
selectedNotificationPayload = notificationAppLaunchDetails!.notificationResponse?.payload;
}
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
InitializationSettings initializationSettings = const InitializationSettings(
android: initializationSettingsAndroid,
);
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse:
(NotificationResponse notificationResponse) {
switch (notificationResponse.notificationResponseType) {
case NotificationResponseType.selectedNotification:
case NotificationResponseType.selectedNotificationAction:
// if (notificationResponse.actionId == navigationActionId) {
selectNotificationSubject.add(notificationResponse.payload);
selectedNotificationPayload = notificationResponse.payload;
// }
didReceiveLocalNotificationSubject.add(
ReceivedNotification(
id: notificationResponse.id!,
title: notificationResponse.actionId,
body: 'stuff',
payload: notificationResponse.payload,
),
);
break;
}
},
// onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
);
_notificationsEnabled = await _isAndroidPermissionGranted();
_notificationsEnabled = await _requestPermissions();
_configureDidReceiveLocalNotificationSubject();
}
and this is the code that gets executed with Workmanager:
void _configureDidReceiveLocalNotificationSubject() {
didReceiveLocalNotificationSubject.stream
.listen((ReceivedNotification receivedNotification) async {
var title = receivedNotification.title ?? 'UNKNOWN';
Workmanager().registerOneOffTask(
"my.simpleTask",
"my.simpleTask",
inputData: <String, dynamic>{
'string': title,
},
);
});
}
Currently I have two problems with that code:
- the Workmanager's task is run only when the user tap the notification
- the Workmanager's task won't be executed if the app is terminated by the user first, even if the notification is generated (and tapped)
How can I make the Workmanager's task to be executed as soon as the notification is generated (without the user tapping) with the application terminated or not?
CodePudding user response:
i assume you are scheduled local notification and execute some function in there.
TL:DR
- first: scheduled local notification not able to execute function in background
eg:
int randomInt = Random().nextInt();
await flutterLocalNotificationsPlugin.zonedSchedule(
0,
'scheduled notif with int $randomInt',
....
when you are registed this notif, you will get randomInt
, and then on the notification it will show the int
that you get first time its scheduled. which means, its only show notification,Random().nextInt
is not executed.
- secondly,
void _configureDidReceiveLocalNotificationSubject() {
didReceiveLocalNotificationSubject.stream
stream function will be terminated too after the apps is killed. except you are bring it into foreground. the stream will keep listening any changes.
How can I make the Workmanager's task to be executed as soon as the notification is generated
I think you are missed on this part. the correct way is:
Register Workmanager
and then inside the callback
function, you can generated local notification
.
- register your WM in your
initState
Workmanager().registerOneOffTask(
"task-identifier",
simpleTaskKey,
initialDelay: Duration(minutes: 30), // you can use this delay for scheduling
);
then in the callback funtion generete local notificaiton
@pragma('vm:entry-point')
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) {
// you function execute here
// eg: final tempInt = Random.nextInt();
// then we can use the tempInt
show local notification function here
return Future.value(true);
});
}