diff --git a/CHANGELOG.md b/CHANGELOG.md index ba2e4a60..96d8c745 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 8.11.0 + +* [**FEAT**] Allow sending Set collection using `FlutterForegroundTask.sendDataToMain` + ## 8.10.4 * [**FIX**] Fixed an issue where main function was called repeatedly when there was no callback to start diff --git a/README.md b/README.md index e2158bb8..d742ceff 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ This plugin is used to implement a foreground service on the Android platform. ## Features * Can perform repetitive tasks with the foreground service. -* Supports two-way communication between the foreground service and UI. -* Provides widget that minimize the app without closing it when the user presses the soft back button. +* Supports two-way communication between the foreground service and UI(main isolate). +* Provides a widget that minimize the app without closing it when the user presses the soft back button. * Provides useful utilities that can use while performing tasks. -* Provides option to automatically resume the foreground service on boot. +* Provides an option to automatically resume the foreground service on boot. ## Support version @@ -21,24 +21,28 @@ This plugin is used to implement a foreground service on the Android platform. - Android: `5.0+ (minSdkVersion: 21)` - iOS: `13.0+` +## Structure + + + ## Getting started To use this plugin, add `flutter_foreground_task` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/). For example: ```yaml dependencies: - flutter_foreground_task: ^8.10.4 + flutter_foreground_task: ^8.11.0 ``` -After adding the `flutter_foreground_task` plugin to the flutter project, we need to specify the permissions and service to use for this plugin to work properly. +After adding the plugin to your flutter project, we need to declare the platform-specific permissions ans service to use for this plugin to work properly. ### :baby_chick: Android -Open the `AndroidManifest.xml` file and specify the service tag inside the `` tag as follows. +Open the `AndroidManifest.xml` file and declare the service tag inside the `` tag as follows. If you want the foreground service to run only when the app is running, add `android:stopWithTask="true"`. -As mentioned in the Android guidelines, to start a FG service on Android 14+, you must specify `android:foregroundServiceType`. +As mentioned in the Android guidelines, to start a FG service on Android 14+, you must declare `android:foregroundServiceType`. * [`camera`](https://developer.android.com/about/versions/14/changes/fgs-types-required#camera) * [`connectedDevice`](https://developer.android.com/about/versions/14/changes/fgs-types-required#connected-device) @@ -54,8 +58,6 @@ As mentioned in the Android guidelines, to start a FG service on Android 14+, yo * [`specialUse`](https://developer.android.com/about/versions/14/changes/fgs-types-required#special-use) * [`systemExempted`](https://developer.android.com/about/versions/14/changes/fgs-types-required#system-exempted) -You can read all the details in the [Android Developer Page](https://developer.android.com/about/versions/14/changes/fgs-types-required) - ``` @@ -79,7 +81,7 @@ Check runtime requirements before starting the service. If this requirement is n ### :baby_chick: iOS -We can also launch `flutter_foreground_task` on the iOS platform. However, it has the following limitations. +You can also run `flutter_foreground_task` on the iOS platform. However, it has the following limitations. * If you force close an app in recent apps, the task will be destroyed immediately. * The task cannot be started automatically on boot like Android OS. @@ -160,7 +162,9 @@ import Flutter GeneratedPluginRegistrant.register(with: self) // here - SwiftFlutterForegroundTaskPlugin.setPluginRegistrantCallback(registerPlugins) + SwiftFlutterForegroundTaskPlugin.setPluginRegistrantCallback { registry in + GeneratedPluginRegistrant.register(with: registry) + } if #available(iOS 10.0, *) { UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate } @@ -168,11 +172,6 @@ import Flutter return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } - -// here -func registerPlugins(registry: FlutterPluginRegistry) { - GeneratedPluginRegistrant.register(with: registry) -} ``` ## How to use @@ -192,10 +191,9 @@ void main() { 2. Write a `TaskHandler` and a `callback` to request starting a TaskHandler. ```dart -// The callback function should always be a top-level function. +// The callback function should always be a top-level or static function. @pragma('vm:entry-point') void startCallback() { - // The setTaskHandler function must be called to handle the task in the background. FlutterForegroundTask.setTaskHandler(MyTaskHandler()); } @@ -496,7 +494,7 @@ Future _stopService() async { ### :hatched_chick: deepening -This plugin supports two-way communication between TaskHandler and UI. +This plugin supports two-way communication between TaskHandler and UI(main isolate). The send function can only send primitive type(int, double, bool), String, Collection(Map, List) provided by Flutter. diff --git a/android/src/main/kotlin/com/pravera/flutter_foreground_task/MethodCallHandlerImpl.kt b/android/src/main/kotlin/com/pravera/flutter_foreground_task/MethodCallHandlerImpl.kt index 9e5ad32b..87cfdbec 100644 --- a/android/src/main/kotlin/com/pravera/flutter_foreground_task/MethodCallHandlerImpl.kt +++ b/android/src/main/kotlin/com/pravera/flutter_foreground_task/MethodCallHandlerImpl.kt @@ -96,9 +96,9 @@ class MethodCallHandlerImpl(private val context: Context, private val provider: "setOnLockScreenVisibility" -> { checkActivityNull().let { - val arguments = args as? Map<*, *> - val isVisible = arguments?.get("isVisible") as? Boolean ?: false - PluginUtils.setOnLockScreenVisibility(it, isVisible) + if (args is Boolean) { + PluginUtils.setOnLockScreenVisibility(it, args) + } } } diff --git a/example/lib/main.dart b/example/lib/main.dart index faf63bad..c7167a30 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -10,10 +10,9 @@ void main() { runApp(const ExampleApp()); } -// The callback function should always be a top-level function. +// The callback function should always be a top-level or static function. @pragma('vm:entry-point') void startCallback() { - // The setTaskHandler function must be called to handle the task in the background. FlutterForegroundTask.setTaskHandler(MyTaskHandler()); } diff --git a/lib/flutter_foreground_task.dart b/lib/flutter_foreground_task.dart index d7cd7fc2..60e8f279 100644 --- a/lib/flutter_foreground_task.dart +++ b/lib/flutter_foreground_task.dart @@ -10,11 +10,10 @@ import 'errors/service_already_started_exception.dart'; import 'errors/service_not_initialized_exception.dart'; import 'errors/service_not_started_exception.dart'; import 'errors/service_timeout_exception.dart'; -import 'models/android_notification_options.dart'; import 'models/foreground_task_options.dart'; -import 'models/ios_notification_options.dart'; import 'models/notification_button.dart'; import 'models/notification_icon_data.dart'; +import 'models/notification_options.dart'; import 'models/notification_permission.dart'; import 'models/service_request_result.dart'; import 'task_handler.dart'; @@ -23,13 +22,12 @@ export 'errors/service_already_started_exception.dart'; export 'errors/service_not_initialized_exception.dart'; export 'errors/service_not_started_exception.dart'; export 'errors/service_timeout_exception.dart'; -export 'models/android_notification_options.dart'; export 'models/foreground_task_event_action.dart'; export 'models/foreground_task_options.dart'; -export 'models/ios_notification_options.dart'; export 'models/notification_button.dart'; export 'models/notification_channel_importance.dart'; export 'models/notification_icon_data.dart'; +export 'models/notification_options.dart'; export 'models/notification_permission.dart'; export 'models/notification_priority.dart'; export 'models/notification_visibility.dart'; diff --git a/lib/flutter_foreground_task_method_channel.dart b/lib/flutter_foreground_task_method_channel.dart index d8978139..0f44c123 100644 --- a/lib/flutter_foreground_task_method_channel.dart +++ b/lib/flutter_foreground_task_method_channel.dart @@ -8,12 +8,12 @@ import 'package:flutter/widgets.dart'; import 'package:platform/platform.dart'; import 'flutter_foreground_task_platform_interface.dart'; -import 'models/android_notification_options.dart'; import 'models/foreground_task_options.dart'; -import 'models/ios_notification_options.dart'; import 'models/notification_button.dart'; import 'models/notification_icon_data.dart'; +import 'models/notification_options.dart'; import 'models/notification_permission.dart'; +import 'models/service_options.dart'; import 'task_handler.dart'; /// An implementation of [FlutterForegroundTaskPlatform] that uses method channels. @@ -43,25 +43,19 @@ class MethodChannelFlutterForegroundTask extends FlutterForegroundTaskPlatform { List? notificationButtons, Function? callback, }) async { - final Map options = { - 'serviceId': serviceId, - if (platform.isAndroid) - ...androidNotificationOptions.toJson() - else if (platform.isIOS) - ...iosNotificationOptions.toJson(), - ...foregroundTaskOptions.toJson(), - 'notificationContentTitle': notificationTitle, - 'notificationContentText': notificationText, - 'iconData': notificationIcon?.toJson(), - 'buttons': notificationButtons?.map((e) => e.toJson()).toList() - }; - - if (callback != null) { - options['callbackHandle'] = - PluginUtilities.getCallbackHandle(callback)?.toRawHandle(); - } - - await mMDChannel.invokeMethod('startService', options); + final Map optionsJson = ServiceStartOptions( + serviceId: serviceId, + androidNotificationOptions: androidNotificationOptions, + iosNotificationOptions: iosNotificationOptions, + foregroundTaskOptions: foregroundTaskOptions, + notificationContentTitle: notificationTitle, + notificationContentText: notificationText, + notificationIcon: notificationIcon, + notificationButtons: notificationButtons, + callback: callback, + ).toJson(platform); + + await mMDChannel.invokeMethod('startService', optionsJson); } @override @@ -78,20 +72,16 @@ class MethodChannelFlutterForegroundTask extends FlutterForegroundTaskPlatform { List? notificationButtons, Function? callback, }) async { - final Map options = { - if (foregroundTaskOptions != null) ...foregroundTaskOptions.toJson(), - 'notificationContentTitle': notificationTitle, - 'notificationContentText': notificationText, - 'iconData': notificationIcon?.toJson(), - 'buttons': notificationButtons?.map((e) => e.toJson()).toList() - }; - - if (callback != null) { - options['callbackHandle'] = - PluginUtilities.getCallbackHandle(callback)?.toRawHandle(); - } - - await mMDChannel.invokeMethod('updateService', options); + final Map optionsJson = ServiceUpdateOptions( + foregroundTaskOptions: foregroundTaskOptions, + notificationContentTitle: notificationTitle, + notificationContentText: notificationText, + notificationIcon: notificationIcon, + notificationButtons: notificationButtons, + callback: callback, + ).toJson(platform); + + await mMDChannel.invokeMethod('updateService', optionsJson); } @override @@ -143,7 +133,7 @@ class MethodChannelFlutterForegroundTask extends FlutterForegroundTaskPlatform { break; case 'onReceiveData': dynamic data = call.arguments; - if (data is List || data is Map) { + if (data is List || data is Map || data is Set) { try { data = jsonDecode(jsonEncode(data)); } catch (e, s) { @@ -189,9 +179,7 @@ class MethodChannelFlutterForegroundTask extends FlutterForegroundTaskPlatform { @override void setOnLockScreenVisibility(bool isVisible) { if (platform.isAndroid) { - mMDChannel.invokeMethod('setOnLockScreenVisibility', { - 'isVisible': isVisible, - }); + mMDChannel.invokeMethod('setOnLockScreenVisibility', isVisible); } } diff --git a/lib/flutter_foreground_task_platform_interface.dart b/lib/flutter_foreground_task_platform_interface.dart index 39579cf0..e10d47a4 100644 --- a/lib/flutter_foreground_task_platform_interface.dart +++ b/lib/flutter_foreground_task_platform_interface.dart @@ -1,11 +1,10 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'flutter_foreground_task_method_channel.dart'; -import 'models/android_notification_options.dart'; import 'models/foreground_task_options.dart'; -import 'models/ios_notification_options.dart'; import 'models/notification_button.dart'; import 'models/notification_icon_data.dart'; +import 'models/notification_options.dart'; import 'models/notification_permission.dart'; import 'task_handler.dart'; diff --git a/lib/models/ios_notification_options.dart b/lib/models/ios_notification_options.dart deleted file mode 100644 index 734564a3..00000000 --- a/lib/models/ios_notification_options.dart +++ /dev/null @@ -1,24 +0,0 @@ -/// Notification options for iOS platform. -class IOSNotificationOptions { - /// Constructs an instance of [IOSNotificationOptions]. - const IOSNotificationOptions({ - this.showNotification = true, - this.playSound = false, - }); - - /// Whether to show notifications. - /// The default is `true`. - final bool showNotification; - - /// Whether to play sound when creating notifications. - /// The default is `false`. - final bool playSound; - - /// Returns the data fields of [IOSNotificationOptions] in JSON format. - Map toJson() { - return { - 'showNotification': showNotification, - 'playSound': playSound, - }; - } -} diff --git a/lib/models/android_notification_options.dart b/lib/models/notification_options.dart similarity index 79% rename from lib/models/android_notification_options.dart rename to lib/models/notification_options.dart index 3c4e05c5..8d67ca70 100644 --- a/lib/models/android_notification_options.dart +++ b/lib/models/notification_options.dart @@ -1,6 +1,6 @@ -import 'package:flutter_foreground_task/models/notification_channel_importance.dart'; -import 'package:flutter_foreground_task/models/notification_priority.dart'; -import 'package:flutter_foreground_task/models/notification_visibility.dart'; +import 'notification_channel_importance.dart'; +import 'notification_priority.dart'; +import 'notification_visibility.dart'; /// Notification options for Android platform. class AndroidNotificationOptions { @@ -91,3 +91,28 @@ class AndroidNotificationOptions { }; } } + +/// Notification options for iOS platform. +class IOSNotificationOptions { + /// Constructs an instance of [IOSNotificationOptions]. + const IOSNotificationOptions({ + this.showNotification = true, + this.playSound = false, + }); + + /// Whether to show notifications. + /// The default is `true`. + final bool showNotification; + + /// Whether to play sound when creating notifications. + /// The default is `false`. + final bool playSound; + + /// Returns the data fields of [IOSNotificationOptions] in JSON format. + Map toJson() { + return { + 'showNotification': showNotification, + 'playSound': playSound, + }; + } +} diff --git a/lib/models/service_options.dart b/lib/models/service_options.dart new file mode 100644 index 00000000..314e112b --- /dev/null +++ b/lib/models/service_options.dart @@ -0,0 +1,94 @@ +import 'dart:ui'; + +import 'package:platform/platform.dart'; + +import 'foreground_task_options.dart'; +import 'notification_button.dart'; +import 'notification_icon_data.dart'; +import 'notification_options.dart'; + +class ServiceStartOptions { + const ServiceStartOptions({ + this.serviceId, + required this.androidNotificationOptions, + required this.iosNotificationOptions, + required this.foregroundTaskOptions, + required this.notificationContentTitle, + required this.notificationContentText, + this.notificationIcon, + this.notificationButtons, + this.callback, + }); + + final int? serviceId; + final AndroidNotificationOptions androidNotificationOptions; + final IOSNotificationOptions iosNotificationOptions; + final ForegroundTaskOptions foregroundTaskOptions; + final String notificationContentTitle; + final String notificationContentText; + final NotificationIconData? notificationIcon; + final List? notificationButtons; + final Function? callback; + + Map toJson(Platform platform) { + final Map json = { + 'serviceId': serviceId, + ...foregroundTaskOptions.toJson(), + 'notificationContentTitle': notificationContentTitle, + 'notificationContentText': notificationContentText, + 'iconData': notificationIcon?.toJson(), + 'buttons': notificationButtons?.map((e) => e.toJson()).toList(), + }; + + if (platform.isAndroid) { + json.addAll(androidNotificationOptions.toJson()); + } else if (platform.isIOS) { + json.addAll(iosNotificationOptions.toJson()); + } + + if (callback != null) { + json['callbackHandle'] = + PluginUtilities.getCallbackHandle(callback!)?.toRawHandle(); + } + + return json; + } +} + +class ServiceUpdateOptions { + const ServiceUpdateOptions({ + required this.foregroundTaskOptions, + required this.notificationContentTitle, + required this.notificationContentText, + this.notificationIcon, + this.notificationButtons, + this.callback, + }); + + final ForegroundTaskOptions? foregroundTaskOptions; + final String? notificationContentTitle; + final String? notificationContentText; + final NotificationIconData? notificationIcon; + final List? notificationButtons; + final Function? callback; + + Map toJson(Platform platform) { + final Map json = { + 'notificationContentTitle': notificationContentTitle, + 'notificationContentText': notificationContentText, + 'iconData': notificationIcon?.toJson(), + 'buttons': notificationButtons?.map((e) => e.toJson()).toList(), + }; + + if (foregroundTaskOptions != null) { + json.addAll(foregroundTaskOptions!.toJson()); + } + + if (callback != null) { + json['callbackHandle'] = + PluginUtilities.getCallbackHandle(callback!)?.toRawHandle(); + } + + return json; + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 3a26330d..aa3cea98 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_foreground_task description: This plugin is used to implement a foreground service on the Android platform. -version: 8.10.4 +version: 8.11.0 homepage: https://github.com/Dev-hwang/flutter_foreground_task environment: diff --git a/test/dummy/service_dummy_data.dart b/test/dummy/service_dummy_data.dart index bfac5945..724f9524 100644 --- a/test/dummy/service_dummy_data.dart +++ b/test/dummy/service_dummy_data.dart @@ -1,7 +1,6 @@ -import 'dart:ui'; - import 'package:flutter/material.dart'; import 'package:flutter_foreground_task/flutter_foreground_task.dart'; +import 'package:flutter_foreground_task/models/service_options.dart'; import 'package:platform/platform.dart'; @pragma('vm:entry-point') @@ -58,32 +57,28 @@ class ServiceDummyData { id: 'id_test2', text: 'test2', textColor: Colors.green), ]; - Map getStartServiceArgs(String platform) { - return { - 'serviceId': serviceId, - if (platform == Platform.android) - ...androidNotificationOptions.toJson() - else if (platform == Platform.iOS) - ...iosNotificationOptions.toJson(), - ...foregroundTaskOptions.toJson(), - 'notificationContentTitle': notificationTitle, - 'notificationContentText': notificationText, - 'iconData': notificationIcon.toJson(), - 'buttons': notificationButtons.map((e) => e.toJson()).toList(), - 'callbackHandle': - PluginUtilities.getCallbackHandle(testCallback)?.toRawHandle(), - }; + Map getStartServiceArgs(Platform platform) { + return ServiceStartOptions( + serviceId: serviceId, + androidNotificationOptions: androidNotificationOptions, + iosNotificationOptions: iosNotificationOptions, + foregroundTaskOptions: foregroundTaskOptions, + notificationContentTitle: notificationTitle, + notificationContentText: notificationText, + notificationIcon: notificationIcon, + notificationButtons: notificationButtons, + callback: testCallback, + ).toJson(platform); } - Map getUpdateServiceArgs() { - return { - ...foregroundTaskOptions.toJson(), - 'notificationContentTitle': notificationTitle, - 'notificationContentText': notificationText, - 'iconData': notificationIcon.toJson(), - 'buttons': notificationButtons.map((e) => e.toJson()).toList(), - 'callbackHandle': - PluginUtilities.getCallbackHandle(testCallback)?.toRawHandle(), - }; + Map getUpdateServiceArgs(Platform platform) { + return ServiceUpdateOptions( + foregroundTaskOptions: foregroundTaskOptions, + notificationContentTitle: notificationTitle, + notificationContentText: notificationText, + notificationIcon: notificationIcon, + notificationButtons: notificationButtons, + callback: testCallback, + ).toJson(platform); } } diff --git a/test/service_api_test.dart b/test/service_api_test.dart index 1a180b28..20b51af9 100644 --- a/test/service_api_test.dart +++ b/test/service_api_test.dart @@ -38,10 +38,10 @@ void main() { }); group('Android', () { - const String platform = Platform.android; + final Platform platform = FakePlatform(operatingSystem: Platform.android); test('init', () { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; expect(FlutterForegroundTask.isInitialized, false); expect(FlutterForegroundTask.androidNotificationOptions, isNull); @@ -66,7 +66,7 @@ void main() { }); test('startService', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; FlutterForegroundTask.skipServiceResponseCheck = true; _init(dummyData); @@ -84,7 +84,7 @@ void main() { }); test('startService (error: ServiceNotInitializedException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; final ServiceRequestResult result = await _startService(dummyData); expect(result.success, false); @@ -92,7 +92,7 @@ void main() { }); test('startService (error: ServiceAlreadyStartedException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; _init(dummyData); @@ -106,7 +106,7 @@ void main() { }); test('startService (error: ServiceTimeoutException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; _init(dummyData); @@ -119,7 +119,7 @@ void main() { }); test('restartService', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; _init(dummyData); @@ -137,7 +137,7 @@ void main() { }); test('restartService (error: ServiceNotStartedException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; final ServiceRequestResult result = await _restartService(); expect(result.success, false); @@ -145,7 +145,7 @@ void main() { }); test('updateService', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; _init(dummyData); @@ -160,13 +160,13 @@ void main() { methodCallHandler.log.last, isMethodCall( ServiceApiMethod.updateService, - arguments: dummyData.getUpdateServiceArgs(), + arguments: dummyData.getUpdateServiceArgs(platform), ), ); }); test('updateService (error: ServiceNotStartedException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; final ServiceRequestResult result = await _updateService(dummyData); expect(result.success, false); @@ -174,7 +174,7 @@ void main() { }); test('stopService', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; FlutterForegroundTask.skipServiceResponseCheck = true; _init(dummyData); @@ -193,7 +193,7 @@ void main() { }); test('stopService (error: ServiceNotStartedException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; final ServiceRequestResult result = await _stopService(); expect(result.success, false); @@ -201,7 +201,7 @@ void main() { }); test('stopService (error: ServiceTimeoutException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; _init(dummyData); @@ -218,7 +218,7 @@ void main() { }); test('isRunningService', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; _init(dummyData); expect(await _isRunningService, false); @@ -258,10 +258,10 @@ void main() { }); group('iOS', () { - const String platform = Platform.iOS; + final Platform platform = FakePlatform(operatingSystem: Platform.iOS); test('init', () { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; expect(FlutterForegroundTask.isInitialized, false); expect(FlutterForegroundTask.androidNotificationOptions, isNull); @@ -286,7 +286,7 @@ void main() { }); test('startService', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; FlutterForegroundTask.skipServiceResponseCheck = true; _init(dummyData); @@ -304,7 +304,7 @@ void main() { }); test('startService (error: ServiceNotInitializedException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; final ServiceRequestResult result = await _startService(dummyData); expect(result.success, false); @@ -312,7 +312,7 @@ void main() { }); test('startService (error: ServiceAlreadyStartedException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; _init(dummyData); @@ -326,7 +326,7 @@ void main() { }); test('startService (error: ServiceTimeoutException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; _init(dummyData); @@ -339,7 +339,7 @@ void main() { }); test('restartService', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; _init(dummyData); @@ -357,7 +357,7 @@ void main() { }); test('restartService (error: ServiceNotStartedException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; final ServiceRequestResult result = await _restartService(); expect(result.success, false); @@ -365,7 +365,7 @@ void main() { }); test('updateService', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; _init(dummyData); @@ -380,13 +380,13 @@ void main() { methodCallHandler.log.last, isMethodCall( ServiceApiMethod.updateService, - arguments: dummyData.getUpdateServiceArgs(), + arguments: dummyData.getUpdateServiceArgs(platform), ), ); }); test('updateService (error: ServiceNotStartedException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; final ServiceRequestResult result = await _updateService(dummyData); expect(result.success, false); @@ -394,7 +394,7 @@ void main() { }); test('stopService', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; FlutterForegroundTask.skipServiceResponseCheck = true; _init(dummyData); @@ -413,7 +413,7 @@ void main() { }); test('stopService (error: ServiceNotStartedException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; final ServiceRequestResult result = await _stopService(); expect(result.success, false); @@ -421,7 +421,7 @@ void main() { }); test('stopService (error: ServiceTimeoutException)', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; _init(dummyData); @@ -438,7 +438,7 @@ void main() { }); test('isRunningService', () async { - platformChannel.platform = FakePlatform(operatingSystem: platform); + platformChannel.platform = platform; _init(dummyData); expect(await _isRunningService, false); diff --git a/test/utility_test.dart b/test/utility_test.dart index 34439548..6bc668d7 100644 --- a/test/utility_test.dart +++ b/test/utility_test.dart @@ -70,7 +70,7 @@ void main() { methodCallHandler.log.last, isMethodCall( UtilityMethod.setOnLockScreenVisibility, - arguments: {'isVisible': true}, + arguments: true, ), ); @@ -79,7 +79,7 @@ void main() { methodCallHandler.log.last, isMethodCall( UtilityMethod.setOnLockScreenVisibility, - arguments: {'isVisible': false}, + arguments: false, ), ); }); @@ -459,12 +459,11 @@ class UtilityMethodCallHandler { } else if (method == UtilityMethod.launchApp) { return Future.value(); } else if (method == UtilityMethod.setOnLockScreenVisibility) { - bool? isVisible; - if (arguments is Map) { - isVisible = arguments['isVisible']; + if (arguments == null) { + throw ArgumentError('The isVisible argument cannot be found.'); } - if (isVisible == null) { - throw ArgumentError('Invalid argument: $arguments'); + if (arguments is! bool) { + throw ArgumentError('The isVisible argument is not of type boolean.'); } return Future.value(); } else if (method == UtilityMethod.isAppOnForeground) {