Open In App

Running Background Tasks in Flutter

Last Updated : 16 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Creating an application that is able to handle processes with background capabilities is crucial for numerous applications, including geolocation, music, or other processes which may take a lot of time. Flutter, an open-source UI toolkit owned by Google lets developers write and compile applications for mobile, web, and desktop all at once.

In this article, we will be learning how to create a sample flutter application that will exhibit background tasking with the aid of the flutter_background package. To conclude this guide, you will have a fully working app that has this continuation to operate even when the app itself is not being used.

How to Build a Background Task App in Flutter

To develop an app that can run tasks in the background using Flutter, you need to follow these steps carefully:

Project Directory Structure

Before diving into the code, let's take a look at the directory structure of our project:

structure
Directory Structure


Steps to Implement Background Tasks in Flutter

To keep an app running in the background in Flutter, you need to use the flutter_background package. This package allows your app to execute tasks even when it is minimized or not actively in use.

Step 1: Create a New Flutter Project

Open your terminal and create a new Flutter project by running the following command:

flutter create background_task_example

Navigate to the project directory:

cd background_task_example

Step 2: Add flutter_background Package to Dependencies

To enable background execution, we need to add the flutter_background package to our project. Open the pubspec.yaml file and add the following dependency:

Dart
dependencies:
  flutter:
    sdk: flutter
  flutter_background: latest_version


Run flutter pub get to install the package.

Add the permissions to your AndroidManifest.xml file :

Open android>app>src>main>AndroidManifest.xml file and put the following permissions under the manifest tag:

    <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

Your AndroidManifest.xml file would look like :

gfg
AndroidManifest.xml

Step 3: Import the Necessary Packages

Import the flutter_background package into your Dart file where you want to manage background tasks:

Dart
import 'package:flutter/material.dart';
import 'package:flutter_background/flutter_background.dart';

Step 4: Initialize the FlutterBackground Package

Before enabling background execution, initialize the flutter_background package with the necessary configurations:

Dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final androidConfig = FlutterBackgroundAndroidConfig(
    notificationTitle: "Background Task Example",
    notificationText: "Running in the background",
    notificationImportance: AndroidNotificationImportance.Default,
    enableWifiLock: true,
  );
  
  bool hasPermissions = await FlutterBackground.initialize(androidConfig: androidConfig);
  
  if (hasPermissions) {
    runApp(MyApp());
  }
}

Here, we initialize the flutter_background package with a custom notification configuration for Android devices. The notificationTitle and notificationText are used to display a notification while the app runs in the background. The enableWifiLock option ensures that the app can maintain a Wi-Fi connection while running in the background, which is useful for tasks like network requests.

Step 5: Create a Background Task and Control Its Execution

To demonstrate how to manage background tasks, we will create methods to start and stop a background task within a StatefulWidget. This background task will simulate a continuous operation by printing a message to the console every few seconds.

Start the Background Task:

The _startBackgroundTask method enables background execution and starts a timer that runs a task periodically.

Dart
void _startBackgroundTask() async {
  bool success = await FlutterBackground.enableBackgroundExecution();
  if (success) {
    setState(() {
      _isRunning = true;
    });
    _timer = Timer.periodic(Duration(seconds: 5), (timer) {
      print("Background task running: ${DateTime.now()}");
    });
  }
}

Background Execution: The FlutterBackground.enableBackgroundExecution() method enables the app to continue running even when it is in the background. If this operation is successful, we proceed to start the timer.

Timer: A Timer is used to simulate a task that repeats every 5 seconds. In this example, the task simply prints the current date and time to the console, indicating that the background task is active.

Stop the Background Task:

The _stopBackgroundTask method stops the timer and disables background execution.

Dart
void _stopBackgroundTask() async {
  _timer?.cancel();
  await FlutterBackground.disableBackgroundExecution();
  setState(() {
    _isRunning = false;
  });
}


Cancel Timer: The cancel() method on the timer stops it from running further, effectively halting the background task.

Disable Background Execution: After stopping the timer, we disable the background execution using FlutterBackground.disableBackgroundExecution(). This step is important to conserve system resources when the background task is no longer needed.

Widget UI:

The widget displays a button that allows the user to start or stop the background task, with text indicating the current status.

Dart
@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Background Task Example'),
    ),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(_isRunning
              ? 'Background task is running...'
              : 'Background task is stopped.'),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: _isRunning ? _stopBackgroundTask : _startBackgroundTask,
            child: Text(_isRunning ? 'Stop Background Task' : 'Start Background Task'),
          ),
        ],
      ),
    ),
  );
}

Step 6: Dispose the Created Controller

It’s important to properly clean up resources when they are no longer needed. In this case, the dispose() method stops the background task if it is running and cleans up the timer to avoid memory leaks.

Dart
@override
void dispose() {
  _stopBackgroundTask();
  super.dispose();
}

Step 7: Run the App

After completing the code, run your app using:

flutter run

Main Dart File: Complete Code

Here's the complete code for the main.dart file:

main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_background/flutter_background.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final androidConfig = FlutterBackgroundAndroidConfig(
    notificationTitle: "Background Task Example",
    notificationText: "Running in the background",
    notificationImportance: AndroidNotificationImportance.Default,
    enableWifiLock: true,
  );
  
  bool hasPermissions = await FlutterBackground.initialize(androidConfig: androidConfig);
  
  if (hasPermissions) {
    runApp(MyApp());
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BackgroundTaskDemo(),
    );
  }
}

class BackgroundTaskDemo extends StatefulWidget {
  @override
  _BackgroundTaskDemoState createState() => _BackgroundTaskDemoState();
}

class _BackgroundTaskDemoState extends State<BackgroundTaskDemo> {
  bool _isRunning = false;
  Timer? _timer;

  void _startBackgroundTask() async {
    bool success = await FlutterBackground.enableBackgroundExecution();
    if (success) {
      setState(() {
        _isRunning = true;
      });
      _timer = Timer.periodic(Duration(seconds: 5), (timer) {
        print("Background task running: ${DateTime.now()}");
      });
    }
  }

  void _stopBackgroundTask() async {
    _timer?.cancel();
    await FlutterBackground.disableBackgroundExecution();
    setState(() {
      _isRunning = false;
    });
  }

  @override
  void dispose() {
    _stopBackgroundTask();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Background Task Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(_isRunning
                ? 'Background task is running...'
                : 'Background task is stopped.'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _isRunning ? _stopBackgroundTask : _startBackgroundTask,
              child: Text(_isRunning ? 'Stop Background Task' : 'Start Background Task'),
            ),
          ],
        ),
      ),
    );
  }
}

Output:

gfg
Logs , printing message after every 5 seconds.


App UI:


Conclusion

In this article, we demonstrated how to create a simple Flutter app that can run tasks in the background using the flutter_background package. This is particularly useful for applications that need to continue working even when not actively used by the user, such as for background location tracking or ongoing network requests. You can now build more complex background operations by extending this basic structure to suit your specific use cases.


Next Article
Article Tags :

Similar Reads