0

I have an app based on flutter and created a Home screen widget for android (with home_widget) showing information from the app. With flutter background_fetch I update these information regularly, which works fine. Now when I restart my phone (emulator or real device), the background_fetch task does not continue, despite headless: true and stopOnTerminate: false set. Instead the old information from the latest fetch before the restart are displayed in the widget again.

main.dart


import 'package:home_widget/home_widget.dart';
import 'package:background_fetch/background_fetch.dart';
import 'package:logging_to_logcat/logging_to_logcat.dart';
import 'package:logging/logging.dart';

void main() {
  runApp(
      const MaterialApp(
          home: MyApp()
      )
  );

  BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);
}



// [Android-only] This "Headless Task" is run when the Android app is terminated with `enableHeadless: true`
// Be sure to annotate your callback function to avoid issues in release mode on Flutter >= 3.3.0
@pragma('vm:entry-point')
void backgroundFetchHeadlessTask(HeadlessTask task) async {
  String taskId = task.taskId;
  bool isTimeout = task.timeout;
  if (isTimeout) {
    // This task has exceeded its allowed running-time.
    // You must stop what you're doing and immediately .finish(taskId)

    debugPrint("[BackgroundFetch] Headless task timed-out: $taskId");
    BackgroundFetch.finish(taskId);
    return;
  }

  HomeWidget.saveWidgetData('refresh_date', "restarted");
  HomeWidget.updateWidget(name: 'WidgetLarge', iOSName: 'WidgetLarge');

  debugPrint('[BackgroundFetch] Headless event received.');
  BackgroundFetch.finish(taskId);
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State createState() {
    return MainPage();
  }
}

class MainPage extends State {
  
  @override
  void initState()  {
    super.initState();
    initPlatformState();

    BackgroundFetch.start().then((int status) {
      debugPrint('[BackgroundFetch] start success: $status');
    }).catchError((e) {
      debugPrint('[BackgroundFetch] start FAILURE: $e');
    });

    HomeWidget.saveWidgetData('refresh_date', "test2");
    HomeWidget.updateWidget(name: 'WidgetLarge', iOSName: 'WidgetLarge');
  }

  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    // Configure BackgroundFetch.
    int status = await BackgroundFetch.configure(BackgroundFetchConfig(
        minimumFetchInterval: 15,
        stopOnTerminate: false,
        enableHeadless: true,
        requiresBatteryNotLow: false,
        requiresCharging: false,
        requiresStorageNotLow: false,
        requiresDeviceIdle: false,
        requiredNetworkType: NetworkType.ANY,
        startOnBoot: true,
        forceAlarmManager: true
    ), (String taskId) async {  // <-- Event handler
      // This is the fetch-event callback.
      print("[BackgroundFetch] Event received $taskId");
      setState(() {
        latestUpdate = DateTime.now();

    HomeWidget.saveWidgetData('refresh_date', "test");
    HomeWidget.updateWidget(name: 'WidgetLarge', iOSName: 'WidgetLarge');
      });
      // IMPORTANT:  You must signal completion of your task or the OS can punish your app
      // for taking too long in the background.
      BackgroundFetch.finish(taskId);
    }, (String taskId) async {  // <-- Task timeout handler.
      // This task has exceeded its allowed running-time.  You must stop what you're doing and immediately .finish(taskId)
      debugPrint("[BackgroundFetch] TASK TIMEOUT taskId: $taskId");
      BackgroundFetch.finish(taskId);
    });

    debugPrint('[BackgroundFetch] configure success: $status');

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;
  }

}

I import background_fetch like this:

dependencies:
  ...
  home_widget: ^0.1.6
  background_fetch:
    git:
      url: https://github.com/transistorsoft/flutter_background_fetch

1 Answers1

0

I just updated flutter to the latest version with flutter upgrade and now it's working. Even tough the headless task begins executing 15 minutes after the reboot, so I still try to figure out how do execute it immediately after the reboot.