### Manage Service Lifecycle Source: https://pub.dev/packages/flutter_foreground_task/example Handles starting and stopping the foreground service, including checking if the service is already running. ```dart Future _startService() async { if (await FlutterForegroundTask.isRunningService) { return FlutterForegroundTask.restartService(); } else { return FlutterForegroundTask.startService( // You can manually specify the foregroundServiceType for the service // to be started, as shown in the comment below. // serviceTypes: [ // ForegroundServiceTypes.dataSync, // ForegroundServiceTypes.remoteMessaging, // ], serviceId: 256, notificationTitle: 'Foreground Service is running', notificationText: 'Tap to return to the app', notificationIcon: null, notificationButtons: [ const NotificationButton(id: 'btn_hello', text: 'hello'), ], notificationInitialRoute: '/second', callback: startCallback, ); } } Future _stopService() { return FlutterForegroundTask.stopService(); } ``` -------------------------------- ### Start Foreground Service Source: https://pub.dev/packages/flutter_foreground_task Starts or restarts the foreground service with specific notification settings and a task callback. ```dart Future _startService() async { if (await FlutterForegroundTask.isRunningService) { return FlutterForegroundTask.restartService(); } else { return FlutterForegroundTask.startService( // You can manually specify the foregroundServiceType for the service // to be started, as shown in the comment below. // serviceTypes: [ // ForegroundServiceTypes.dataSync, // ForegroundServiceTypes.remoteMessaging, // ], serviceId: 256, notificationTitle: 'Foreground Service is running', notificationText: 'Tap to return to the app', notificationIcon: null, notificationButtons: [ const NotificationButton(id: 'btn_hello', text: 'hello'), ], notificationInitialRoute: '/', callback: startCallback, ); } } ``` -------------------------------- ### Deprecated Color Property Usage Source: https://pub.dev/packages/flutter_foreground_task/score Example of a deprecated color property access identified during static analysis. Use the recommended color calculation formula instead. ```dart ╷ 4 │ String get toRgbString => '$red,$green,$blue'; │ ^^^ ╵ ``` -------------------------------- ### Deprecated WillPopScope Usage Source: https://pub.dev/packages/flutter_foreground_task/score Example of a deprecated WillPopScope usage identified during static analysis. Replace with PopScope to support Android predictive back navigation. ```dart ╷ 31 │ WillPopScope(onWillPop: _onWillPop, child: widget.child); │ ^^^^^^^^^^^^ ╵ ``` -------------------------------- ### Initialize Foreground Service and Permissions Source: https://pub.dev/packages/flutter_foreground_task Handles notification permissions, battery optimization settings, and service initialization configuration. ```dart Future _requestPermissions() async { // Android 13+, you need to allow notification permission to display foreground service notification. // // iOS: If you need notification, ask for permission. final NotificationPermission notificationPermission = await FlutterForegroundTask.checkNotificationPermission(); if (notificationPermission != NotificationPermission.granted) { await FlutterForegroundTask.requestNotificationPermission(); } if (Platform.isAndroid) { // Android 12+, there are restrictions on starting a foreground service. // // To restart the service on device reboot or unexpected problem, you need to allow below permission. if (!await FlutterForegroundTask.isIgnoringBatteryOptimizations) { // This function requires `android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` permission. await FlutterForegroundTask.requestIgnoreBatteryOptimization(); } // Use this utility only if you provide services that require long-term survival, // such as exact alarm service, healthcare service, or Bluetooth communication. // // This utility requires the "android.permission.SCHEDULE_EXACT_ALARM" permission. // Using this permission may make app distribution difficult due to Google policy. if (!await FlutterForegroundTask.canScheduleExactAlarms) { // When you call this function, will be gone to the settings page. // So you need to explain to the user why set it. await FlutterForegroundTask.openAlarmsAndRemindersSettings(); } } } void _initService() { FlutterForegroundTask.init( androidNotificationOptions: AndroidNotificationOptions( channelId: 'foreground_service', channelName: 'Foreground Service Notification', channelDescription: 'This notification appears when the foreground service is running.', onlyAlertOnce: true, ), iosNotificationOptions: const IOSNotificationOptions( showNotification: false, playSound: false, ), foregroundTaskOptions: ForegroundTaskOptions( eventAction: ForegroundTaskEventAction.repeat(5000), autoRunOnBoot: true, autoRunOnMyPackageReplaced: true, allowWakeLock: true, allowWifiLock: true, ), ); } @override void initState() { super.initState(); // Add a callback to receive data sent from the TaskHandler. FlutterForegroundTask.addTaskDataCallback(_onReceiveTaskData); WidgetsBinding.instance.addPostFrameCallback((_) { // Request permissions and initialize the service. _requestPermissions(); _initService(); }); } ``` -------------------------------- ### Second Page Implementation Source: https://pub.dev/packages/flutter_foreground_task/example A simple page demonstrating navigation and popping. ```dart class SecondPage extends StatelessWidget { const SecondPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Second Page'), centerTitle: true, ), body: Center( child: ElevatedButton( onPressed: Navigator.of(context).pop, child: const Text('pop this page'), ), ), ); } } ``` -------------------------------- ### Configure AppDelegate for Swift Source: https://pub.dev/packages/flutter_foreground_task Register the plugin callback in the AppDelegate for Swift projects. ```swift import UIKit import Flutter @main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) // this SwiftFlutterForegroundTaskPlugin.setPluginRegistrantCallback { registry in GeneratedPluginRegistrant.register(with: registry) } if #available(iOS 10.0, *) { UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate } return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } ``` -------------------------------- ### Configure Info.plist for Background Tasks Source: https://pub.dev/packages/flutter_foreground_task Add these keys to ios/Runner/info.plist to enable background task execution and fetch modes. ```xml BGTaskSchedulerPermittedIdentifiers com.pravera.flutter_foreground_task.refresh UIBackgroundModes fetch ``` -------------------------------- ### Add dependency via command line Source: https://pub.dev/packages/flutter_foreground_task/install Use this command in your terminal to automatically add the package to your project. ```bash $ flutter pub add flutter_foreground_task ``` -------------------------------- ### Build UI Components Source: https://pub.dev/packages/flutter_foreground_task/example Helper methods to build the communication data display and service control buttons. ```dart Widget _buildCommunicationDataText() { return ValueListenableBuilder( valueListenable: _taskDataListenable, builder: (context, data, _) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('You received data from TaskHandler:'), Text('$data', style: Theme.of(context).textTheme.headlineMedium), ], ), ); }, ); } Widget _buildServiceControlButtons() { buttonBuilder(String text, {VoidCallback? onPressed}) { return ElevatedButton( onPressed: onPressed, child: Text(text), ); } return Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ buttonBuilder('start service', onPressed: _startService), buttonBuilder('stop service', onPressed: _stopService), buttonBuilder('increment count', onPressed: _incrementCount), ], ), ); } ``` -------------------------------- ### Initialize Foreground Service Source: https://pub.dev/packages/flutter_foreground_task/example Configures Android and iOS notification settings and task options for the foreground service. ```dart void _initService() { FlutterForegroundTask.init( androidNotificationOptions: AndroidNotificationOptions( channelId: 'foreground_service', channelName: 'Foreground Service Notification', channelDescription: 'This notification appears when the foreground service is running.', onlyAlertOnce: true, ), iosNotificationOptions: const IOSNotificationOptions( showNotification: false, playSound: false, ), foregroundTaskOptions: ForegroundTaskOptions( eventAction: ForegroundTaskEventAction.repeat(5000), autoRunOnBoot: true, autoRunOnMyPackageReplaced: true, allowWakeLock: true, allowWifiLock: true, ), ); } ``` -------------------------------- ### Handle Streams in TaskHandler Source: https://pub.dev/packages/flutter_foreground_task Demonstrates managing stream subscriptions within a TaskHandler, ensuring proper cleanup in onDestroy. ```dart class MyTaskHandler extends TaskHandler { StreamSubscription? _streamSubscription; @override Future onStart(DateTime timestamp, TaskStarter starter) async { _streamSubscription = FlLocation.getLocationStream().listen((location) { final String message = '${location.latitude}, ${location.longitude}'; FlutterForegroundTask.updateService(notificationText: message); // Send data to main isolate. final String locationJson = jsonEncode(location.toJson()); FlutterForegroundTask.sendDataToMain(locationJson); }); } @override void onRepeatEvent(DateTime timestamp) { // not use } @override Future onDestroy(DateTime timestamp, bool isTimeout) async { _streamSubscription?.cancel(); _streamSubscription = null; } } ``` -------------------------------- ### Configure AppDelegate for Objective-C Source: https://pub.dev/packages/flutter_foreground_task Register the plugin callback in the AppDelegate for Objective-C projects. ```objective-c #import "AppDelegate.h" #import "GeneratedPluginRegistrant.h" // this #import // this void registerPlugins(NSObject* registry) { [GeneratedPluginRegistrant registerWithRegistry:registry]; } @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; // this [FlutterForegroundTaskPlugin setPluginRegistrantCallback:registerPlugins]; if (@available(iOS 10.0, *)) { [UNUserNotificationCenter currentNotificationCenter].delegate = (id) self; } return [super application:application didFinishLaunchingWithOptions:launchOptions]; } @end ``` -------------------------------- ### Define Task Handlers and Options Source: https://pub.dev/packages/flutter_foreground_task Configures foreground task options and implements TaskHandler classes to manage background events and service updates. ```dart final ForegroundTaskOptions defaultTaskOptions = ForegroundTaskOptions( eventAction: ForegroundTaskEventAction.repeat(5000), autoRunOnBoot: true, autoRunOnMyPackageReplaced: true, allowWakeLock: true, allowWifiLock: true, ); @pragma('vm:entry-point') void startCallback() { FlutterForegroundTask.setTaskHandler(FirstTaskHandler()); } class FirstTaskHandler extends TaskHandler { int _count = 0; @override Future onStart(DateTime timestamp, TaskStarter starter) async { // some code } @override void onRepeatEvent(DateTime timestamp) { _count++; if (_count == 10) { FlutterForegroundTask.updateService( foregroundTaskOptions: defaultTaskOptions.copyWith( eventAction: ForegroundTaskEventAction.repeat(1000), ), callback: updateCallback, ); return; } FlutterForegroundTask.updateService( notificationTitle: 'Hello FirstTaskHandler :)', notificationText: timestamp.toString(), ); // Send data to main isolate. final Map data = { "timestampMillis": timestamp.millisecondsSinceEpoch, }; FlutterForegroundTask.sendDataToMain(data); } @override Future onDestroy(DateTime timestamp, bool isTimeout) async { // some code } } @pragma('vm:entry-point') void updateCallback() { FlutterForegroundTask.setTaskHandler(SecondTaskHandler()); } class SecondTaskHandler extends TaskHandler { @override Future onStart(DateTime timestamp, TaskStarter starter) async { // some code } @override void onRepeatEvent(DateTime timestamp) { FlutterForegroundTask.updateService( notificationTitle: 'Hello SecondTaskHandler :)', notificationText: timestamp.toString(), ); // Send data to main isolate. final Map data = { "timestampMillis": timestamp.millisecondsSinceEpoch, }; FlutterForegroundTask.sendDataToMain(data); } @override Future onDestroy(DateTime timestamp, bool isTimeout) async { // some code } } ``` -------------------------------- ### Configure Bridging Header for Swift Source: https://pub.dev/packages/flutter_foreground_task Add the import statement to the Runner-Bridging-Header.h file for Swift projects. ```objective-c #import ``` -------------------------------- ### Configure AndroidManifest.xml Source: https://pub.dev/packages/flutter_foreground_task Declare required permissions and the foreground service component within the application tag. ```xml ``` -------------------------------- ### Import the package Source: https://pub.dev/packages/flutter_foreground_task/install Include this import statement in your Dart files to access the package functionality. ```dart import 'package:flutter_foreground_task/flutter_foreground_task.dart'; ``` -------------------------------- ### Handle Task Communication Source: https://pub.dev/packages/flutter_foreground_task/example Methods for receiving data from the background task and sending commands to it. ```dart void _onReceiveTaskData(Object data) { print('onReceiveTaskData: $data'); _taskDataListenable.value = data; } void _incrementCount() { FlutterForegroundTask.sendDataToTask(MyTaskHandler.incrementCountCommand); } ``` -------------------------------- ### UI Integration with WithForegroundTask Source: https://pub.dev/packages/flutter_foreground_task/example Wraps the Scaffold with WithForegroundTask to enable app minimization behavior when the back button is pressed. ```dart @override Widget build(BuildContext context) { // ** optional ** // A widget that minimize the app without closing it when the user presses // the soft back button. It only works when the service is running. // // This widget must be declared above the [Scaffold] widget. return WithForegroundTask( child: Scaffold( appBar: AppBar( title: const Text('Flutter Foreground Task'), centerTitle: true, ), body: SafeArea( child: Column( children: [ Expanded(child: _buildCommunicationDataText()), _buildServiceControlButtons(), ], ), ), ), ); } ``` -------------------------------- ### Initialize Communication Port Source: https://pub.dev/packages/flutter_foreground_task Call initCommunicationPort in the main function to enable communication between the TaskHandler and the UI. ```dart void main() { // Initialize port for communication between TaskHandler and UI. FlutterForegroundTask.initCommunicationPort(); runApp(const ExampleApp()); } ``` -------------------------------- ### Manage Plugin Data Storage Source: https://pub.dev/packages/flutter_foreground_task Provides methods for saving, retrieving, and removing data within the plugin's storage scope. ```dart void function() async { await FlutterForegroundTask.getData(key: String); await FlutterForegroundTask.getAllData(); await FlutterForegroundTask.saveData(key: String, value: Object); await FlutterForegroundTask.removeData(key: String); await FlutterForegroundTask.clearAllData(); } ``` -------------------------------- ### Define TaskHandler and Callback Source: https://pub.dev/packages/flutter_foreground_task Implement a TaskHandler class and a top-level or static callback function to manage foreground task lifecycle events. ```dart // The callback function should always be a top-level or static function. @pragma('vm:entry-point') void startCallback() { FlutterForegroundTask.setTaskHandler(MyTaskHandler()); } class MyTaskHandler extends TaskHandler { // Called when the task is started. @override Future onStart(DateTime timestamp, TaskStarter starter) async { print('onStart(starter: ${starter.name})'); } // Called based on the eventAction set in ForegroundTaskOptions. @override void onRepeatEvent(DateTime timestamp) { // Send data to main isolate. final Map data = { "timestampMillis": timestamp.millisecondsSinceEpoch, }; FlutterForegroundTask.sendDataToMain(data); } // Called when the task is destroyed. @override Future onDestroy(DateTime timestamp, bool isTimeout) async { print('onDestroy(isTimeout: $isTimeout)'); } // Called when data is sent using `FlutterForegroundTask.sendDataToTask`. @override void onReceiveData(Object data) { print('onReceiveData: $data'); } // Called when the notification button is pressed. @override void onNotificationButtonPressed(String id) { print('onNotificationButtonPressed: $id'); } // Called when the notification itself is pressed. @override void onNotificationPressed() { print('onNotificationPressed'); } // Called when the notification itself is dismissed. @override void onNotificationDismissed() { print('onNotificationDismissed'); } } ``` -------------------------------- ### Implement Foreground Service Task Handler Source: https://pub.dev/packages/flutter_foreground_task/example Defines a custom TaskHandler to manage service lifecycle events and communication. The callback function must be top-level or static. ```dart import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_foreground_task/flutter_foreground_task.dart'; void main() { // Initialize port for communication between TaskHandler and UI. FlutterForegroundTask.initCommunicationPort(); runApp(const ExampleApp()); } // The callback function should always be a top-level or static function. @pragma('vm:entry-point') void startCallback() { FlutterForegroundTask.setTaskHandler(MyTaskHandler()); } class MyTaskHandler extends TaskHandler { static const String incrementCountCommand = 'incrementCount'; int _count = 0; void _incrementCount() { _count++; // Update notification content. FlutterForegroundTask.updateService( notificationTitle: 'Hello MyTaskHandler :)', notificationText: 'count: $_count', ); // Send data to main isolate. FlutterForegroundTask.sendDataToMain(_count); } // Called when the task is started. @override Future onStart(DateTime timestamp, TaskStarter starter) async { print('onStart(starter: ${starter.name})'); _incrementCount(); } // Called based on the eventAction set in ForegroundTaskOptions. @override void onRepeatEvent(DateTime timestamp) { _incrementCount(); } // Called when the task is destroyed. @override Future onDestroy(DateTime timestamp, bool isTimeout) async { print('onDestroy(isTimeout: $isTimeout)'); } // Called when data is sent using `FlutterForegroundTask.sendDataToTask`. @override void onReceiveData(Object data) { print('onReceiveData: $data'); if (data == incrementCountCommand) { _incrementCount(); } } // Called when the notification button is pressed. @override void onNotificationButtonPressed(String id) { print('onNotificationButtonPressed: $id'); } // Called when the notification itself is pressed. @override void onNotificationPressed() { print('onNotificationPressed'); } // Called when the notification itself is dismissed. @override void onNotificationDismissed() { print('onNotificationDismissed'); } } class ExampleApp extends StatelessWidget { const ExampleApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( routes: { '/': (context) => const ExamplePage(), '/second': (context) => const SecondPage(), }, initialRoute: '/', ); } } class ExamplePage extends StatefulWidget { const ExamplePage({super.key}); @override State createState() => _ExamplePageState(); } class _ExamplePageState extends State { final ValueNotifier _taskDataListenable = ValueNotifier(null); Future _requestPermissions() async { // Android 13+, you need to allow notification permission to display foreground service notification. // // iOS: If you need notification, ask for permission. final NotificationPermission notificationPermission = await FlutterForegroundTask.checkNotificationPermission(); if (notificationPermission != NotificationPermission.granted) { await FlutterForegroundTask.requestNotificationPermission(); } if (Platform.isAndroid) { // Android 12+, there are restrictions on starting a foreground service. // // To restart the service on device reboot or unexpected problem, you need to allow below permission. if (!await FlutterForegroundTask.isIgnoringBatteryOptimizations) { // This function requires `android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` permission. await FlutterForegroundTask.requestIgnoreBatteryOptimization(); } // Use this utility only if you provide services that require long-term survival, // such as exact alarm service, healthcare service, or Bluetooth communication. // // This utility requires the "android.permission.SCHEDULE_EXACT_ALARM" permission. // Using this permission may make app distribution difficult due to Google policy. if (!await FlutterForegroundTask.canScheduleExactAlarms) { // When you call this function, will be gone to the settings page. // So you need to explain to the user why set it. await FlutterForegroundTask.openAlarmsAndRemindersSettings(); } } } ``` -------------------------------- ### Add dependency to pubspec.yaml Source: https://pub.dev/packages/flutter_foreground_task/install Manually add this line to your pubspec.yaml file to include the package in your dependencies. ```yaml dependencies: flutter_foreground_task: ^10.0.0 ``` -------------------------------- ### Send Data from UI to Task Source: https://pub.dev/packages/flutter_foreground_task Sends data from the main UI isolate to the TaskHandler, requiring JSON-compatible formats for Maps. ```dart // Main(UI) void _sendDataToTask() { // Main(UI) -> TaskHandler // // The Map collection can only be sent in json format, such as Map. FlutterForegroundTask.sendDataToTask(Object); } // TaskHandler @override void onReceiveData(Object data) { print('onReceiveData: $data'); // You can cast it to any type you want using the Collection.cast function. if (data is List) { final List intList = data.cast(); } } ``` -------------------------------- ### Lifecycle Integration Source: https://pub.dev/packages/flutter_foreground_task/example Registers and removes data callbacks during widget lifecycle events. ```dart @override void initState() { super.initState(); // Add a callback to receive data sent from the TaskHandler. FlutterForegroundTask.addTaskDataCallback(_onReceiveTaskData); WidgetsBinding.instance.addPostFrameCallback((_) { // Request permissions and initialize the service. _requestPermissions(); _initService(); }); } @override void dispose() { // Remove a callback to receive data sent from the TaskHandler. FlutterForegroundTask.removeTaskDataCallback(_onReceiveTaskData); _taskDataListenable.dispose(); super.dispose(); } ``` -------------------------------- ### Send Data from Task to UI Source: https://pub.dev/packages/flutter_foreground_task Sends primitive data or collections from the TaskHandler to the main UI isolate. ```dart // TaskHandler @override Future onStart(DateTime timestamp, TaskStarter starter) async { // TaskHandler -> Main(UI) FlutterForegroundTask.sendDataToMain(Object); } // Main(UI) void _onReceiveTaskData(Object data) { print('onReceiveTaskData: $data'); } ``` -------------------------------- ### Manage Task Data Callbacks Source: https://pub.dev/packages/flutter_foreground_task Register and remove data callbacks in the widget lifecycle to handle messages sent from the TaskHandler. ```dart void _onReceiveTaskData(Object data) { if (data is Map) { final dynamic timestampMillis = data["timestampMillis"]; if (timestampMillis != null) { final DateTime timestamp = DateTime.fromMillisecondsSinceEpoch(timestampMillis, isUtc: true); print('timestamp: ${timestamp.toString()}'); } } } @override void initState() { super.initState(); // Add a callback to receive data sent from the TaskHandler. FlutterForegroundTask.addTaskDataCallback(_onReceiveTaskData); } @override void dispose() { // Remove a callback to receive data sent from the TaskHandler. FlutterForegroundTask.removeTaskDataCallback(_onReceiveTaskData); super.dispose(); } ``` -------------------------------- ### Stop Foreground Service Source: https://pub.dev/packages/flutter_foreground_task Terminates the active foreground service. ```dart Future _stopService() { return FlutterForegroundTask.stopService(); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.