How can I keep background tasks alive in background on Android using Flutter?

1,650

You probably want an Android service to run these tasks (foreground or background depending on your specific requirements).

It looks like there are some Flutter packages that have already been built to help with this, but I'd pay close attention to what they offer in terms of support for different Android versions.

Share:
1,650
Lucas Correa
Author by

Lucas Correa

Updated on December 27, 2022

Comments

  • Lucas Correa
    Lucas Correa over 1 year

    I have a bussness app that count time, set macros and show notification and alerts. I have a problem when app goes to background and Android stop my counting tasks.

    I tried many things to keep these tasks alive, but I failed. This notification need to work offline, so FCM not a good solution.

    How can I work arround it?

    Obs.: When app goes to foreground, all tasks work and show all notifications... But I need to alert user just in time, not only in foreground.


    I founded a solution!

    Searching the site https://dontkillmyapp.com/ I saw many apps with the same problem and some solution ideas for differets brands and models.

    After checking some of them, I saw that many installed apps has this config for default, so I search how can I do it programactlly.

    Here the solution:

    pubspec.yaml

      android_power_manager: ^0.1.6
      permission_handler: ^5.0.1+1
    

    Function:

    void init() async {
        var status = await Permission.ignoreBatteryOptimizations.status;
        print("status: $status");
        if (status.isGranted) {
          print(
              "isIgnoring: ${(await AndroidPowerManager.isIgnoringBatteryOptimizations)}");
          if (!(await AndroidPowerManager.isIgnoringBatteryOptimizations)) {
            AndroidPowerManager.requestIgnoreBatteryOptimizations();
          }
        } else {
          Map<Permission, PermissionStatus> statuses = await [
            Permission.ignoreBatteryOptimizations,
          ].request();
          print(
              "permission value: ${statuses[Permission.ignoreBatteryOptimizations]}");
          if (statuses[Permission.ignoreBatteryOptimizations].isGranted) {
            AndroidPowerManager.requestIgnoreBatteryOptimizations();
          } else {
            exit(0);
          }
        }
      }
    

    AppWidget.dart (main)

      @override
      Widget build(BuildContext context) {
        init();
    
        SystemChrome.setPreferredOrientations([
          DeviceOrientation.portraitUp,
          DeviceOrientation.portraitDown,
        ]);
        DataTransferService().initTimerTask();
        return MaterialApp(
          navigatorKey: Modular.navigatorKey,
          title: APP_NAME,
          theme: ThemeData(
            primarySwatch: Colors.green,
          ),
          initialRoute: '/',
          routes: {
            '/': (context) => LoginPage(),
            '/home': (context) => HomePage(),
            '/notification': (context) => NotificationPage(),
            '/alerts': (context) => AlertsPage(),
          },
          onGenerateRoute: Modular.generateRoute,
        );
      }
    

    So, the app ask permission (if needed) and, if permission is granted, ask user to set app to ignore battery optimization.

    Now the notifications are working all rigt! =]

    • SardorbekR
      SardorbekR almost 3 years
      did you add "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" in your manifest? and won't this lead to reject of play store?
    • Lucas Correa
      Lucas Correa almost 3 years
      Yes. In final solution I used this permission. Play Store accept, but flagged that I have ads in my app... I don't know why, but still works
  • Lucas Correa
    Lucas Correa about 3 years
    I search a lot in your "logic" and I found one solution (for while) I will edit my post to share this solution