Skip to content

Commit 0dd1557

Browse files
committed
feat: Add notificationInitialRoute option to service function
1 parent 25ffd65 commit 0dd1557

File tree

9 files changed

+96
-23
lines changed

9 files changed

+96
-23
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,18 @@ class MyTaskHandler extends TaskHandler {
227227
void onNotificationButtonPressed(String id) {
228228
print('onNotificationButtonPressed: $id');
229229
}
230+
231+
// Called when the notification itself is pressed.
232+
@override
233+
void onNotificationPressed() {
234+
print('onNotificationPressed');
235+
}
236+
237+
// Called when the notification itself is dismissed.
238+
@override
239+
void onNotificationDismissed() {
240+
print('onNotificationDismissed');
241+
}
230242
}
231243
```
232244

@@ -337,6 +349,7 @@ void initState() {
337349
* `notificationText`: The text to display in the notification.
338350
* `notificationIcon`: The icon to display in the notification. Go to [this page](./documentation/customize_notification_icon.md) to customize.
339351
* `notificationButtons`: The buttons to display in the notification. (can add 0~3 buttons)
352+
* `notificationInitialRoute`: Initial route to be used when the app is launched via a notification. Works the same as the `launchApp` utility.
340353
* `callback`: A top-level function that calls the setTaskHandler function.
341354

342355
```dart
@@ -352,6 +365,7 @@ Future<ServiceRequestResult> _startService() async {
352365
notificationButtons: [
353366
const NotificationButton(id: 'btn_hello', text: 'hello'),
354367
],
368+
notificationInitialRoute: '/',
355369
callback: startCallback,
356370
);
357371
}

android/src/main/kotlin/com/pravera/flutter_foreground_task/PreferencesKey.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ object PreferencesKey {
3737
const val NOTIFICATION_CONTENT_TEXT = "notificationContentText"
3838
const val NOTIFICATION_CONTENT_ICON = "icon"
3939
const val NOTIFICATION_CONTENT_BUTTONS = "buttons"
40+
const val NOTIFICATION_INITIAL_ROUTE = "initialRoute"
4041

4142
// task options
4243
const val FOREGROUND_TASK_OPTIONS_PREFS = prefix + "FOREGROUND_TASK_OPTIONS"

android/src/main/kotlin/com/pravera/flutter_foreground_task/models/NotificationContent.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ data class NotificationContent(
99
val title: String,
1010
val text: String,
1111
val icon: NotificationIcon?,
12-
val buttons: List<NotificationButton>
12+
val buttons: List<NotificationButton>,
13+
val initialRoute: String?
1314
) {
1415
companion object {
1516
fun getData(context: Context): NotificationContent {
@@ -35,11 +36,14 @@ data class NotificationContent(
3536
}
3637
}
3738

39+
val initialRoute = prefs.getString(PrefsKey.NOTIFICATION_INITIAL_ROUTE, null)
40+
3841
return NotificationContent(
3942
title = title,
4043
text = text,
4144
icon = icon,
42-
buttons = buttons
45+
buttons = buttons,
46+
initialRoute = initialRoute
4347
)
4448
}
4549

@@ -62,11 +66,14 @@ data class NotificationContent(
6266
buttonsJsonString = JSONArray(buttonsJson).toString()
6367
}
6468

69+
val initialRoute = map?.get(PrefsKey.NOTIFICATION_INITIAL_ROUTE) as? String
70+
6571
with(prefs.edit()) {
6672
putString(PrefsKey.NOTIFICATION_CONTENT_TITLE, title)
6773
putString(PrefsKey.NOTIFICATION_CONTENT_TEXT, text)
6874
putString(PrefsKey.NOTIFICATION_CONTENT_ICON, iconJsonString)
6975
putString(PrefsKey.NOTIFICATION_CONTENT_BUTTONS, buttonsJsonString)
76+
putString(PrefsKey.NOTIFICATION_INITIAL_ROUTE, initialRoute)
7077
commit()
7178
}
7279
}
@@ -90,11 +97,14 @@ data class NotificationContent(
9097
buttonsJsonString = JSONArray(buttonsJson).toString()
9198
}
9299

100+
val initialRoute = map?.get(PrefsKey.NOTIFICATION_INITIAL_ROUTE) as? String
101+
93102
with(prefs.edit()) {
94103
title?.let { putString(PrefsKey.NOTIFICATION_CONTENT_TITLE, it) }
95104
text?.let { putString(PrefsKey.NOTIFICATION_CONTENT_TEXT, it) }
96105
iconJsonString?.let { putString(PrefsKey.NOTIFICATION_CONTENT_ICON, it) }
97106
buttonsJsonString?.let { putString(PrefsKey.NOTIFICATION_CONTENT_BUTTONS, it) }
107+
initialRoute?.let { putString(PrefsKey.NOTIFICATION_INITIAL_ROUTE, it) }
98108
commit()
99109
}
100110
}

android/src/main/kotlin/com/pravera/flutter_foreground_task/service/ForegroundService.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,12 @@ class ForegroundService : Service() {
488488
val packageName = applicationContext.packageName
489489
val intent = packageManager.getLaunchIntentForPackage(packageName)?.apply {
490490
putExtra(INTENT_DATA_NAME, ACTION_NOTIFICATION_PRESSED)
491+
492+
// set initialRoute
493+
val initialRoute = notificationContent.initialRoute
494+
if (initialRoute != null) {
495+
putExtra("route", initialRoute)
496+
}
491497
}
492498

493499
var flags = PendingIntent.FLAG_UPDATE_CURRENT

example/lib/main.dart

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ class MyTaskHandler extends TaskHandler {
6767
void onNotificationButtonPressed(String id) {
6868
print('onNotificationButtonPressed: $id');
6969
}
70+
71+
// Called when the notification itself is pressed.
72+
@override
73+
void onNotificationPressed() {
74+
print('onNotificationPressed');
75+
}
76+
77+
// Called when the notification itself is dismissed.
78+
@override
79+
void onNotificationDismissed() {
80+
print('onNotificationDismissed');
81+
}
7082
}
7183

7284
class ExampleApp extends StatelessWidget {
@@ -77,6 +89,7 @@ class ExampleApp extends StatelessWidget {
7789
return MaterialApp(
7890
routes: {
7991
'/': (context) => const ExamplePage(),
92+
'/second': (context) => const SecondPage(),
8093
},
8194
initialRoute: '/',
8295
);
@@ -162,6 +175,7 @@ class _ExamplePageState extends State<ExamplePage> {
162175
notificationButtons: [
163176
const NotificationButton(id: 'btn_hello', text: 'hello'),
164177
],
178+
notificationInitialRoute: '/second',
165179
callback: startCallback,
166180
);
167181
}
@@ -210,31 +224,23 @@ class _ExamplePageState extends State<ExamplePage> {
210224
// This widget must be declared above the [Scaffold] widget.
211225
return WithForegroundTask(
212226
child: Scaffold(
213-
appBar: _buildAppBar(),
214-
body: _buildContent(),
215-
),
216-
);
217-
}
218-
219-
AppBar _buildAppBar() {
220-
return AppBar(
221-
title: const Text('Flutter Foreground Task'),
222-
centerTitle: true,
223-
);
224-
}
225-
226-
Widget _buildContent() {
227-
return SafeArea(
228-
child: Column(
229-
children: [
230-
Expanded(child: _buildCommunicationText()),
231-
_buildServiceControlButtons(),
232-
],
227+
appBar: AppBar(
228+
title: const Text('Flutter Foreground Task'),
229+
centerTitle: true,
230+
),
231+
body: SafeArea(
232+
child: Column(
233+
children: [
234+
Expanded(child: _buildCommunicationDataText()),
235+
_buildServiceControlButtons(),
236+
],
237+
),
238+
),
233239
),
234240
);
235241
}
236242

237-
Widget _buildCommunicationText() {
243+
Widget _buildCommunicationDataText() {
238244
return ValueListenableBuilder(
239245
valueListenable: _taskDataListenable,
240246
builder: (context, data, _) {
@@ -272,3 +278,23 @@ class _ExamplePageState extends State<ExamplePage> {
272278
);
273279
}
274280
}
281+
282+
class SecondPage extends StatelessWidget {
283+
const SecondPage({super.key});
284+
285+
@override
286+
Widget build(BuildContext context) {
287+
return Scaffold(
288+
appBar: AppBar(
289+
title: const Text('Second Page'),
290+
centerTitle: true,
291+
),
292+
body: Center(
293+
child: ElevatedButton(
294+
onPressed: Navigator.of(context).pop,
295+
child: const Text('pop this page'),
296+
),
297+
),
298+
);
299+
}
300+
}

lib/flutter_foreground_task.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class FlutterForegroundTask {
100100
required String notificationText,
101101
NotificationIcon? notificationIcon,
102102
List<NotificationButton>? notificationButtons,
103+
String? notificationInitialRoute,
103104
Function? callback,
104105
}) async {
105106
try {
@@ -120,6 +121,7 @@ class FlutterForegroundTask {
120121
notificationText: notificationText,
121122
notificationIcon: notificationIcon,
122123
notificationButtons: notificationButtons,
124+
notificationInitialRoute: notificationInitialRoute,
123125
callback: callback,
124126
);
125127

@@ -155,6 +157,7 @@ class FlutterForegroundTask {
155157
String? notificationText,
156158
NotificationIcon? notificationIcon,
157159
List<NotificationButton>? notificationButtons,
160+
String? notificationInitialRoute,
158161
Function? callback,
159162
}) async {
160163
try {
@@ -168,6 +171,7 @@ class FlutterForegroundTask {
168171
notificationTitle: notificationTitle,
169172
notificationIcon: notificationIcon,
170173
notificationButtons: notificationButtons,
174+
notificationInitialRoute: notificationInitialRoute,
171175
callback: callback,
172176
);
173177

lib/flutter_foreground_task_method_channel.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class MethodChannelFlutterForegroundTask extends FlutterForegroundTaskPlatform {
4141
required String notificationText,
4242
NotificationIcon? notificationIcon,
4343
List<NotificationButton>? notificationButtons,
44+
String? notificationInitialRoute,
4445
Function? callback,
4546
}) async {
4647
final Map<String, dynamic> optionsJson = ServiceStartOptions(
@@ -52,6 +53,7 @@ class MethodChannelFlutterForegroundTask extends FlutterForegroundTaskPlatform {
5253
notificationContentText: notificationText,
5354
notificationIcon: notificationIcon,
5455
notificationButtons: notificationButtons,
56+
notificationInitialRoute: notificationInitialRoute,
5557
callback: callback,
5658
).toJson(platform);
5759

@@ -70,6 +72,7 @@ class MethodChannelFlutterForegroundTask extends FlutterForegroundTaskPlatform {
7072
String? notificationText,
7173
NotificationIcon? notificationIcon,
7274
List<NotificationButton>? notificationButtons,
75+
String? notificationInitialRoute,
7376
Function? callback,
7477
}) async {
7578
final Map<String, dynamic> optionsJson = ServiceUpdateOptions(
@@ -78,6 +81,7 @@ class MethodChannelFlutterForegroundTask extends FlutterForegroundTaskPlatform {
7881
notificationContentText: notificationText,
7982
notificationIcon: notificationIcon,
8083
notificationButtons: notificationButtons,
84+
notificationInitialRoute: notificationInitialRoute,
8185
callback: callback,
8286
).toJson(platform);
8387

lib/flutter_foreground_task_platform_interface.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ abstract class FlutterForegroundTaskPlatform extends PlatformInterface {
4141
required String notificationText,
4242
NotificationIcon? notificationIcon,
4343
List<NotificationButton>? notificationButtons,
44+
String? notificationInitialRoute,
4445
Function? callback,
4546
}) {
4647
throw UnimplementedError('startService() has not been implemented.');
@@ -56,6 +57,7 @@ abstract class FlutterForegroundTaskPlatform extends PlatformInterface {
5657
String? notificationText,
5758
NotificationIcon? notificationIcon,
5859
List<NotificationButton>? notificationButtons,
60+
String? notificationInitialRoute,
5961
Function? callback,
6062
}) {
6163
throw UnimplementedError('updateService() has not been implemented.');

lib/models/service_options.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class ServiceStartOptions {
1717
required this.notificationContentText,
1818
this.notificationIcon,
1919
this.notificationButtons,
20+
this.notificationInitialRoute,
2021
this.callback,
2122
});
2223

@@ -28,6 +29,7 @@ class ServiceStartOptions {
2829
final String notificationContentText;
2930
final NotificationIcon? notificationIcon;
3031
final List<NotificationButton>? notificationButtons;
32+
final String? notificationInitialRoute;
3133
final Function? callback;
3234

3335
Map<String, dynamic> toJson(Platform platform) {
@@ -38,6 +40,7 @@ class ServiceStartOptions {
3840
'notificationContentText': notificationContentText,
3941
'icon': notificationIcon?.toJson(),
4042
'buttons': notificationButtons?.map((e) => e.toJson()).toList(),
43+
'initialRoute': notificationInitialRoute,
4144
};
4245

4346
if (platform.isAndroid) {
@@ -62,6 +65,7 @@ class ServiceUpdateOptions {
6265
required this.notificationContentText,
6366
this.notificationIcon,
6467
this.notificationButtons,
68+
this.notificationInitialRoute,
6569
this.callback,
6670
});
6771

@@ -70,6 +74,7 @@ class ServiceUpdateOptions {
7074
final String? notificationContentText;
7175
final NotificationIcon? notificationIcon;
7276
final List<NotificationButton>? notificationButtons;
77+
final String? notificationInitialRoute;
7378
final Function? callback;
7479

7580
Map<String, dynamic> toJson(Platform platform) {
@@ -78,6 +83,7 @@ class ServiceUpdateOptions {
7883
'notificationContentText': notificationContentText,
7984
'icon': notificationIcon?.toJson(),
8085
'buttons': notificationButtons?.map((e) => e.toJson()).toList(),
86+
'initialRoute': notificationInitialRoute,
8187
};
8288

8389
if (foregroundTaskOptions != null) {

0 commit comments

Comments
 (0)