transistorsoft / flutter_background_fetch

Periodic callbacks in the background for both IOS and Android. Includes Android Headless mechanism
MIT License
571 stars 167 forks source link

The application fails to start. #226

Closed Gcii closed 3 years ago

Gcii commented 3 years ago

Hi. The emulator works correctly, it does the tasks in time and without errors. but I did launch the application to be tested on a Xiaomi mi 10 pro and the application goes into a failure mode. you can move around the application but nothing can be seen. I used the sample app from the package and as I already mentioned, in the emulator it works fine. Apparently, the application enters this state of failure, when I open the application and a few seconds before the task had been executed in the background. the emulator model is a pixel 3a and the physical cell phone is a xioami mi 10 pro. the error occurs few times, but 80% of the time is when I open the application and a few seconds before the task was executed in the background.

christocracy commented 3 years ago

You must not ignore the issue template.

Your Environment

To Reproduce Steps to reproduce the behavior:

Debug logs

Additional context Add any other context about the problem here.

Gcii commented 3 years ago

Plugin version: 1.0.0 and earlier. Plataform: Android. OS version: Emulator (Pixel a3)-- Android 11 and Physical cell phone (Xiaomi MI 10 pro)-- Android 11 Device manufacturer / model: Emulator (Pixel a3) and Physical cell phone (Xiaomi MI 10 pro with MIUI 12.6 21.6.9 beta)

Flutter doctor: Doctor summary (to see all details, run flutter doctor -v): [√] Flutter (Channel stable, 2.2.2, on Microsoft Windows [Versión 10.0.19041.1052], locale es-MX) [√] Android toolchain - develop for Android devices (Android SDK version 30.0.3) [√] Android Studio [√] VS Code (version 1.57.0)
[√] Connected device (1 available)

• No issues found!

Plugin config:

package io.flutter.plugins;

import androidx.annotation.Keep;
import androidx.annotation.NonNull;

import io.flutter.embedding.engine.FlutterEngine;

/**
 * Generated file. Do not edit.
 * This file is generated by the Flutter tool based on the
 * plugins that support the Android platform.
 */
@Keep
public final class GeneratedPluginRegistrant {
  public static void registerWith(@NonNull FlutterEngine flutterEngine) {
    flutterEngine.getPlugins().add(new com.transistorsoft.flutter.backgroundfetch.BackgroundFetchPlugin());
    flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin());
    flutterEngine.getPlugins().add(new io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin());
    flutterEngine.getPlugins().add(new com.tekartik.sqflite.SqflitePlugin());
  }
}

To reproduce Steps to reproduce the behavior:

I use this code:

void backgroundFetchHeadlessTask(HeadlessTask task) async {
  var taskId = task.taskId;
  var timeout = task.timeout;
  if (timeout) {
    print("[BackgroundFetch] Headless task timed-out: $taskId");
    BackgroundFetch.finish(taskId);
    return;
  }
  print("[BackgroundFetch] Headless event received: $taskId");
  var timestamp = DateTime.now();
  var prefs = await SharedPreferences.getInstance();
  var events = <String>[];
  var json = prefs.getString(EVENTS_KEY);
  if (json != null) {
    events = jsonDecode(json).cast<String>();
  }
  events.insert(0, "$taskId@$timestamp [Headless]");
  prefs.setString(EVENTS_KEY, jsonEncode(events));

  if (taskId == 'flutter_background_fetch') {
    BackgroundFetch.scheduleTask(TaskConfig(
        taskId: "com.transistorsoft.customtask",
        delay: 5000,
        periodic: false,
        forceAlarmManager: false,
        stopOnTerminate: false,
        enableHeadless: true
    ));
  }

void main() {
  runApp(MyApp());
  BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);
}
class MyApp extends StatefulWidget {
  const MyApp({Key key}) : super(key: key);
  @override
  TabBar createState() {
    return TabBar();
  }
class TabBar extends State<MyApp > with TickerProviderStateMixin {
  TabController _tabController;
  MediaQueryData mqPantalla = MediaQueryData.fromWindow(window);

Future<void> initPlatformState() async {
    // Load persisted fetch events from SharedPreferences
    var prefs = await SharedPreferences.getInstance();
    var json = prefs.getString(EVENTS_KEY);
    if (json != null) {
      setState(() {
        _events = jsonDecode(json).cast<String>();
      });
    }

    // Configure BackgroundFetch.
    try {
      var status = await BackgroundFetch.configure(BackgroundFetchConfig(
        minimumFetchInterval: 15,
        forceAlarmManager: false,
        stopOnTerminate: false,
        startOnBoot: true,
        enableHeadless: true,
        requiresBatteryNotLow: false,
        requiresCharging: false,
        requiresStorageNotLow: false,
        requiresDeviceIdle: false,
        requiredNetworkType: NetworkType.NONE,
      ), _onBackgroundFetch, _onBackgroundFetchTimeout);
      print('[BackgroundFetch] configure success: $status');
      setState(() {
        _status = status;
      });

      // Schedule a "one-shot" custom-task in 10000ms.
      // These are fairly reliable on Android (particularly with forceAlarmManager) but not iOS,
      // where device must be powered (and delay will be throttled by the OS).
      BackgroundFetch.scheduleTask(TaskConfig(
          taskId: "com.transistorsoft.customtask",
          delay: 10000,
          periodic: false,
          forceAlarmManager: true,
          stopOnTerminate: false,
          enableHeadless: true
      ));

    } catch(e) {
      print("[BackgroundFetch] configure ERROR: $e");
      setState(() {
        _status = e;
      });
    }

    // 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;
  }

  void _onBackgroundFetch(String taskId) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    DateTime timestamp = new DateTime.now();
    // This is the fetch-event callback.
    print("[BackgroundFetch] Event received: $taskId");
    setState(() {
      _events.insert(0, "$taskId@${timestamp.toString()}");
    });
    // Persist fetch events in SharedPreferences
    prefs.setString(EVENTS_KEY, jsonEncode(_events));

    if (taskId == "flutter_background_fetch") {
      // Schedule a one-shot task when fetch event received (for testing).
      /*
      BackgroundFetch.scheduleTask(TaskConfig(
          taskId: "com.transistorsoft.customtask",
          delay: 5000,
          periodic: false,
          forceAlarmManager: true,
          stopOnTerminate: false,
          enableHeadless: true,
          requiresNetworkConnectivity: true,
          requiresCharging: true
      ));
       */
    }
    // IMPORTANT:  You must signal completion of your fetch task or the OS can punish your app
    // for taking too long in the background.
    BackgroundFetch.finish(taskId);
  }

  /// This event fires shortly before your task is about to timeout.  You must finish any outstanding work and call BackgroundFetch.finish(taskId).
  void _onBackgroundFetchTimeout(String taskId) {
    print("[BackgroundFetch] TIMEOUT: $taskId");
    BackgroundFetch.finish(taskId);
  }

  void initState() {
    try {
      super.initState();
      initPlatformState();
      Timer.periodic(new Duration(seconds: 2), (timer) {
        BackgroundFetch.start().then((int status) {
          print('[BackgroundFetch] se inició exitosamente: $status');
        }).catchError((e) {
          print('[BackgroundFetch] error al iniciar: $e');
        });
        timer.cancel();
      });
      _tabController = TabController(length: 3, vsync: this);
      _tabController.index = 1;
      _tabController.addListener(_handleSelected);
    } catch (e) {}
  }

  void _handleSelected() {
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    try {
      return MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          splashColor: Colors.transparent,
          bottomSheetTheme: BottomSheetThemeData(
            backgroundColor: Colors.transparent,
          ),
        ),
        home: Scaffold(
          resizeToAvoidBottomInset: false,
          appBar: AppBar(
            toolbarHeight: 0,
            elevation: 0,
            backgroundColor: Colors.teal[400],
          ),
          backgroundColor: Colors.white,
          bottomSheet: Container(
            decoration: BoxDecoration(
              borderRadius: BorderRadius.only(
                topLeft: Radius.elliptical(30, 20),
                topRight: Radius.elliptical(30, 20),
              ),
              color: Colors.teal[300],
            ),
            child: TabBar(
                indicatorColor: Colors.teal[300],
                indicatorSize: TabBarIndicatorSize.label,
                controller: _tabController,
                labelPadding: EdgeInsets.all(0),
                indicatorPadding: EdgeInsets.all(0),
                enableFeedback: false,
                tabs: [
                  Container(
                    decoration: BoxDecoration(
                      color: Colors.teal[300],
                      borderRadius: BorderRadius.only(
                        topLeft: Radius.elliptical(30, 20),
                      ),
                    ),
                    width: mqPantalla.size.width / 3,
                    height: 55.9870,
                    child: MaterialButton(
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.only(
                        topLeft: Radius.elliptical(30, 20),
                      )),
                      highlightElevation: 0,
                      padding: EdgeInsets.all(0),
                      elevation: 0,
                      enableFeedback: false,
                      highlightColor: Colors.teal[100],
                      splashColor: Colors.transparent,
                      onPressed: () {
                        _tabController.index = 0;
                      },
                      child: Icon(
                        Icons.ac_unit,
                        size: 30
                        color: _tabController.index == 0
                            ? Colors.white
                            : Colors.black,
                      ),
                    ),
                  ),
                  Container(
                    decoration: BoxDecoration(
                      color: Colors.teal[300],
                    ),
                    width: mqPantalla.size.width / 3,
                    height: 55.987,
                    child: MaterialButton(
                      highlightElevation: 0,
                      padding: EdgeInsets.all(0),
                      elevation: 0,
                      enableFeedback: false,
                      highlightColor: Colors.teal[100],
                      splashColor: Colors.transparent,
                      onPressed: () async {
                        _tabController.index = 1;
                      },
                      child: Icon(
                        Icons.ac_unit,
                        size: 30
                        color: _tabController.index == 1
                            ? Colors.white
                            : Colors.black,
                      ),
                    ),
                  ),
                  Container(
                    decoration: BoxDecoration(
                      color: Colors.teal[300],
                      borderRadius: BorderRadius.only(
                        topRight: Radius.elliptical(30, 20),
                      ),
                    ),
                    width: mqPantalla.size.width / 3,
                    height: 30
                    child: MaterialButton(
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.only(
                        topRight: Radius.elliptical(30, 20),
                      )),
                      highlightElevation: 0,
                      padding: EdgeInsets.all(0),
                      elevation: 0,
                      enableFeedback: false,
                      highlightColor: Colors.teal[100],
                      splashColor: Colors.transparent,
                      onPressed: () {
                        _tabController.index = 2;
                      },
                      child: Icon(
                        Icons.ac_unit
                        size: 30
                        color: _tabController.index == 2
                            ? Colors.white
                            : Colors.black,
                      ),
                    ),
                  ),
                ]),
          ),
          body: TabBarView(
              controller: _tabController,
              physics: NeverScrollableScrollPhysics(),
              children: [
               Icons.ac_unit,
                Icons.ac_unit_outlined,
                Icons.ac_unit_rounded
              ]),
        ),
        title: "A",
      );
    } catch (e) {
      return Container(height: 200, width: 200, color: Colors.red);
    }
  }
}

2.- then i do a release with this: flutter build apk --release 3.- install app on xiaomi 4.- open app for several seconds. 5.- close application 6.- remove app from multitasking 7.- open application every 10 minutes and repeat step 4, 5 and 6.

the error is only when the application starts. it only happens a few times. I have a screenshot of the error, but I don't know how to upload images here.

christocracy commented 3 years ago

Please learn how to Syntax Highlight Code Blocks.

Edit your issue.

Gcii commented 3 years ago

ok thanks, and i have a screenshot of the error in case you like to see it. in the emulator it works correctly... the problem is with the release

christocracy commented 3 years ago

I have a screenshot of the error

When you have an Android error, the first thing to do, before posting an issue, is grab the error logs from $ adb logcat.

Gcii commented 3 years ago

The error is in the physical device. The error is that the application does not load well. everything remains blank and the screens do not load except for some icons and that's all.

I don't know how to get $ adb logcat. of the physical device. I have not been able to replicate the error in the emulator.

give me a moment to use the command adb logca on the physical device.

christocracy commented 3 years ago

I don't know how to get $ adb logcat. of the physical device.

Gcii commented 3 years ago
7223 W MessageQueue: java.lang.IllegalStateException: Handler (com.miui.powerkeeper.feedbackcontrol.FeedbackControlService$FeedbackControlHandler) {9457912} sending message to a Handler on a dead thread

I copied the moment when the app opens correctly and copied when the app crashes.

There are differences between when it is opened well and when it was opened badly, but it is too much information and I don't know if it is sensitive information to share everything.

the main differences. When the application opens fine, background fetch starts successfully.

when the application crashes, background fetch does not start.

and when the app opens correctly I have this

 16628 16628 D TSBackgroundFetch: - configure
 16628 16628 D TSBackgroundFetch: - start
 16628 16628 D TSBackgroundFetch: - registerTask: flutter_background_fetch
  1001  1071 W SurfaceFlinger: eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]
  1001  3989 W SurfaceFlinger: eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]
 16628 16628 D TSBackgroundFetch: {
 16628 16628 D TSBackgroundFetch:   "taskId": "flutter_background_fetch",
 16628 16628 D TSBackgroundFetch:   "isFetchTask": true,
 16628 16628 D TSBackgroundFetch:   "minimumFetchInterval": 15,
 16628 16628 D TSBackgroundFetch:   "stopOnTerminate": false,
 16628 16628 D TSBackgroundFetch:   "requiredNetworkType": 0,
 16628 16628 D TSBackgroundFetch:   "requiresBatteryNotLow": false,
 16628 16628 D TSBackgroundFetch:   "requiresCharging": false,
 16628 16628 D TSBackgroundFetch:   "requiresDeviceIdle": false,
 16628 16628 D TSBackgroundFetch:   "requiresStorageNotLow": false,
 16628 16628 D TSBackgroundFetch:   "startOnBoot": true,
 16628 16628 D TSBackgroundFetch:   "jobService": "com.transistorsoft.flutter.backgroundfetch.HeadlessTask",
 16628 16628 D TSBackgroundFetch:   "forceAlarmManager": true,
 16628 16628 D TSBackgroundFetch:   "periodic": true,
 16628 16628 D TSBackgroundFetch:   "delay": -1
 16628 16628 D TSBackgroundFetch: }
 16628 16655 I flutter : [BackgroundFetch] configuraci├│n exitosa: 2
 16628 16628 D DecorView[]: getWindowModeFromSystem  windowmode is 1
 16628 16628 D DecorView:  old windowMode:1 new windowMode: 1 isNeedToChangeCaptionView false
 16628 16628 D DecorView[]: updateDecorCaptionStatus displayWindowDecor is false
  2702  2702 D StatusBar: disable<e i a s b h r c s > disable2<q i n >
  1001  1072 W SurfaceFlinger: eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]
  1001  3989 W SurfaceFlinger: eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]
 16628 16628 D TSBackgroundFetch: - registerTask: com.transistorsoft.customtask
 16628 16628 D TSBackgroundFetch: {
 16628 16628 D TSBackgroundFetch:   "taskId": "com.transistorsoft.customtask",
 16628 16628 D TSBackgroundFetch:   "isFetchTask": false,
 16628 16628 D TSBackgroundFetch:   "minimumFetchInterval": 15,
 16628 16628 D TSBackgroundFetch:   "stopOnTerminate": false,
 16628 16628 D TSBackgroundFetch:   "requiredNetworkType": 0,
 16628 16628 D TSBackgroundFetch:   "requiresBatteryNotLow": false,
 16628 16628 D TSBackgroundFetch:   "requiresCharging": false,
 16628 16628 D TSBackgroundFetch:   "requiresDeviceIdle": false,
 16628 16628 D TSBackgroundFetch:   "requiresStorageNotLow": false,
 16628 16628 D TSBackgroundFetch:   "startOnBoot": false,
 16628 16628 D TSBackgroundFetch:   "jobService": "com.transistorsoft.flutter.backgroundfetch.HeadlessTask",
 16628 16628 D TSBackgroundFetch:   "forceAlarmManager": true,
 16628 16628 D TSBackgroundFetch:   "periodic": false,
 16628 16628 D TSBackgroundFetch:   "delay": 10000
 16628 16628 D TSBackgroundFetch: }
   932   932 I ANDR-PERF-LM: LMPerfGlue: perfmodule_submit_request() 132: perfmodule_submit_request()
   932   932 I ANDR-PERF-LM: Core: getInstance() 84: LM getInstance
   932   932 I ANDR-PERF-LM: WQ: push() 59: LMTriggerQ push() size=0
   932   932 I ANDR-PERF-LM: WQ: push() 61: LMTriggerQ push() done size=1
   932  1123 I ANDR-PERF-LM: WQ: pop() 42: LMTriggerQ pop() done size=0
   932  1123 I ANDR-PERF-LM: Core: lmMain() 373: Waiting on trigger Queue
   932  1123 I ANDR-PERF-LM: WQ: pop() 31: LMTriggerQ pop() size=0
.
.
.
.
.
10 16535 I sensors-hal: ssc_conn_event_cb:492, event[0] msg_id=1025, ts=32369023641
   910 16535 I sensors-hal: ssc_conn_event_cb:492, event[0] msg_id=1025, ts=32372828995
   910 16535 I sensors-hal: ssc_conn_event_cb:492, event[0] msg_id=1025, ts=32376634350
 16628 16628 D TSBackgroundFetch: - start
 16628 16628 D TSBackgroundFetch: - registerTask: flutter_background_fetch
 16628 16628 D TSBackgroundFetch: {
 16628 16628 D TSBackgroundFetch:   "taskId": "flutter_background_fetch",
 16628 16628 D TSBackgroundFetch:   "isFetchTask": true,
 16628 16628 D TSBackgroundFetch:   "minimumFetchInterval": 15,
 16628 16628 D TSBackgroundFetch:   "stopOnTerminate": false,
 16628 16628 D TSBackgroundFetch:   "requiredNetworkType": 0,
 16628 16628 D TSBackgroundFetch:   "requiresBatteryNotLow": false,
 16628 16628 D TSBackgroundFetch:   "requiresCharging": false,
 16628 16628 D TSBackgroundFetch:   "requiresDeviceIdle": false,
 16628 16628 D TSBackgroundFetch:   "requiresStorageNotLow": false,
 16628 16628 D TSBackgroundFetch:   "startOnBoot": true,
 16628 16628 D TSBackgroundFetch:   "jobService": "com.transistorsoft.flutter.backgroundfetch.HeadlessTask",
 16628 16628 D TSBackgroundFetch:   "forceAlarmManager": true,
 16628 16628 D TSBackgroundFetch:   "periodic": true,
 16628 16628 D TSBackgroundFetch:   "delay": -1
 16628 16628 D TSBackgroundFetch: }
 16628 16655 I flutter : [BackgroundFetch] se inici├│ exitosamente: 2

and when the application opens wrong I have this

 1001  1072 W SurfaceFlinger: eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]
  1001  3989 W SurfaceFlinger: eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]
 16079 16079 D TSBackgroundFetch: - configure
 16079 16079 D TSBackgroundFetch: - start
 16079 16079 D TSBackgroundFetch: - registerTask: flutter_background_fetch
 16079 16079 D TSBackgroundFetch: {
 16079 16079 D TSBackgroundFetch:   "taskId": "flutter_background_fetch",
 16079 16079 D TSBackgroundFetch:   "isFetchTask": true,
 16079 16079 D TSBackgroundFetch:   "minimumFetchInterval": 15,
 16079 16079 D TSBackgroundFetch:   "stopOnTerminate": false,
 16079 16079 D TSBackgroundFetch:   "requiredNetworkType": 0,
 16079 16079 D TSBackgroundFetch:   "requiresBatteryNotLow": false,
 16079 16079 D TSBackgroundFetch:   "requiresCharging": false,
 16079 16079 D TSBackgroundFetch:   "requiresDeviceIdle": false,
 16079 16079 D TSBackgroundFetch:   "requiresStorageNotLow": false,
 16079 16079 D TSBackgroundFetch:   "startOnBoot": true,
 16079 16079 D TSBackgroundFetch:   "jobService": "com.transistorsoft.flutter.backgroundfetch.HeadlessTask",
 16079 16079 D TSBackgroundFetch:   "forceAlarmManager": true,
 16079 16079 D TSBackgroundFetch:   "periodic": true,
 16079 16079 D TSBackgroundFetch:   "delay": -1
 16079 16079 D TSBackgroundFetch: }
 16079 16983 I flutter : [BackgroundFetch] configuraci├│n exitosa: 2
 16079 16079 D TSBackgroundFetch: - registerTask: com.transistorsoft.customtask
 16079 16079 D TSBackgroundFetch: {
 16079 16079 D TSBackgroundFetch:   "taskId": "com.transistorsoft.customtask",
 16079 16079 D TSBackgroundFetch:   "isFetchTask": false,
 16079 16079 D TSBackgroundFetch:   "minimumFetchInterval": 15,
 16079 16079 D TSBackgroundFetch:   "stopOnTerminate": false,
 16079 16079 D TSBackgroundFetch:   "requiredNetworkType": 0,
 16079 16079 D TSBackgroundFetch:   "requiresBatteryNotLow": false,
 16079 16079 D TSBackgroundFetch:   "requiresCharging": false,
 16079 16079 D TSBackgroundFetch:   "requiresDeviceIdle": false,
 16079 16079 D TSBackgroundFetch:   "requiresStorageNotLow": false,
 16079 16079 D TSBackgroundFetch:   "startOnBoot": false,
 16079 16079 D TSBackgroundFetch:   "jobService": "com.transistorsoft.flutter.backgroundfetch.HeadlessTask",
 16079 16079 D TSBackgroundFetch:   "forceAlarmManager": true,
 16079 16079 D TSBackgroundFetch:   "periodic": false,
 16079 16079 D TSBackgroundFetch:   "delay": 10000
 16079 16079 D TSBackgroundFetch: }
  1001  1072 W SurfaceFlinger: eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]
  1001  1072 W SurfaceFlinger: eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]
  3032 13013 W FloatingIconLayer: release
   932   932 I ANDR-PERF-LM: LMPerfGlue: perfmodule_submit_request() 132: perfmodule_submit_request()
   932   932 I ANDR-PERF-LM: Core: getInstance() 84: LM getInstance
   932   932 I ANDR-PERF-LM: WQ: push() 59: LMTriggerQ push() size=0
   932   932 I ANDR-PERF-LM: WQ: push() 61: LMTriggerQ push() done size=1
   932  1123 I ANDR-PERF-LM: WQ: pop() 42: LMTriggerQ pop() done size=0
   932  1123 I ANDR-PERF-LM: Core: lmMain() 373: Waiting on trigger Queue
   932  1123 I ANDR-PERF-LM: WQ: pop() 31: LMTriggerQ pop() size=0

  1873  2229 I ActivityManager: Start proc 16994:com.xxx.nameAPP/u0a418 for broadcast {com.xxx.nameAPP/com.transistorsoft.tsbackgroundfetch.FetchAlarmReceiver}

 16994 16994 D TSBackgroundFetch: - Background Fetch event received: com.transistorsoft.customtask
  1873  2521 I MiuiNetworkPolicy: updateUidState uid = 10418, uidState = 19
 16994 16994 D TSBackgroundFetch: ­ƒÆÇ [HeadlessTask com.transistorsoft.customtask]

 16994 16994 D TSBackgroundFetch: [HeadlessTask] waiting for client to initialize
   910 16746 I sensors-hal: ssc_conn_event_cb:492, event[0] msg_id=1025, ts=35952963761
 16994 16994 I TSBackgroundFetch: $ initialized
 16994 17020 I flutter : [BackgroundFetch] Evento recibido en background: com.transistorsoft.customtask
 16994 17020 I flutter : com.transistorsoft.customtask@2021-06-15 15:11:21.938818 [backGround]
 16994 17020 I flutter :  bg por shared *******************************
 16994 17020 I flutter :  1623787881938 *******************************
 16994 16994 D TSBackgroundFetch: - finish: com.transistorsoft.customtask
 16994 16994 D TSBackgroundFetch: - FetchAlarmReceiver finish
christocracy commented 3 years ago

I don't see any problem related to the plugin in your logs.

I suggest you install the /example app on your device and test that.

Gcii commented 3 years ago

I am reading the logs that I got yesterday and when the application opens fine I have this:

I ActivityManager: Start proc 16628:com.gcii.myapp/u0a418 for pre-top-activity {com.gcii.myapp/com.example.myapp.MainActivity} caller=com.miui.home

and when the application opens wrong I have this:

I ActivityTaskManager: The Process com.gcii.myapp Already Exists in BG. So sending its PID: 16079

and apparently the application never starts

christocracy commented 3 years ago

I suggest you install the /example app In this repo. Do not look at the code, just install it on your device.

Gcii commented 3 years ago

I test your code on my cell phone and apparently it doesn't fail.

I added some things to your code, here I leave them.

/* */ MediaQueryData mqPantalla = MediaQueryData.fromWindow(window); //global variable

and i put this in the class _MyAppState

with TickerProviderStateMixin 
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
  TabController _tabController; // I added this
  bool _enabled = true;
  int _status = 0;
  List<String> _events = [];

  @override
  void initState() {
    super.initState();
    initPlatformState();
  //*****************************************************************************************************************//
  //********************************************* I added this ******************************************************//
  //*****************************************************************************************************************//
    _tabController = TabController(length: 3, vsync: this);
    _tabController.index = 1;
    _tabController.addListener(_handleSelected);
  }

  void _handleSelected() {
    setState(() {});
  }
      //*****************************************************************************************************************//
      //*****************************************************************************************************************//
      //*****************************************************************************************************************//
  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    // Load persisted fetch events from SharedPreferences
    var prefs = await SharedPreferences.getInstance();
    var json = prefs.getString(EVENTS_KEY);
    if (json != null) {
      setState(() {
        _events = jsonDecode(json).cast<String>();
      });
    }

    // Configure BackgroundFetch.
    try {
      var status = await BackgroundFetch.configure(
          BackgroundFetchConfig(
            minimumFetchInterval: 15,
            forceAlarmManager: false,
            stopOnTerminate: false,
            startOnBoot: true,
            enableHeadless: true,
            requiresBatteryNotLow: false,
            requiresCharging: false,
            requiresStorageNotLow: false,
            requiresDeviceIdle: false,
            requiredNetworkType: NetworkType.NONE,
          ),
          _onBackgroundFetch,
          _onBackgroundFetchTimeout);
      print('[BackgroundFetch] configure success: $status');
      setState(() {
        _status = status;
      });

      // Schedule a "one-shot" custom-task in 10000ms.
      // These are fairly reliable on Android (particularly with forceAlarmManager) but not iOS,
      // where device must be powered (and delay will be throttled by the OS).
      BackgroundFetch.scheduleTask(TaskConfig(
          taskId: "com.transistorsoft.customtask",
          delay: 10000,
          periodic: false,
          forceAlarmManager: true,
          stopOnTerminate: false,
          enableHeadless: true));
    } catch (e) {
      print("[BackgroundFetch] configure ERROR: $e");
      setState(() {
        _status = e;
      });
    }

    // 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;
  }

  void _onBackgroundFetch(String taskId) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    DateTime timestamp = new DateTime.now();
    // This is the fetch-event callback.
    print("[BackgroundFetch] Event received: $taskId");
    setState(() {
      _events.insert(0, "$taskId@${timestamp.toString()}");
    });
    // Persist fetch events in SharedPreferences
    prefs.setString(EVENTS_KEY, jsonEncode(_events));

    if (taskId == "flutter_background_fetch") {
      // Schedule a one-shot task when fetch event received (for testing).
      /*
      BackgroundFetch.scheduleTask(TaskConfig(
          taskId: "com.transistorsoft.customtask",
          delay: 5000,
          periodic: false,
          forceAlarmManager: true,
          stopOnTerminate: false,
          enableHeadless: true,
          requiresNetworkConnectivity: true,
          requiresCharging: true
      ));
       */
    }
    // IMPORTANT:  You must signal completion of your fetch task or the OS can punish your app
    // for taking too long in the background.
    BackgroundFetch.finish(taskId);
  }

  /// This event fires shortly before your task is about to timeout.  You must finish any outstanding work and call BackgroundFetch.finish(taskId).
  void _onBackgroundFetchTimeout(String taskId) {
    print("[BackgroundFetch] TIMEOUT: $taskId");
    BackgroundFetch.finish(taskId);
  }

  void _onClickEnable(enabled) {
    setState(() {
      _enabled = enabled;
    });
    if (enabled) {
      BackgroundFetch.start().then((int status) {
        print('[BackgroundFetch] start success: $status');
      }).catchError((e) {
        print('[BackgroundFetch] start FAILURE: $e');
      });
    } else {
      BackgroundFetch.stop().then((int status) {
        print('[BackgroundFetch] stop success: $status');
      });
    }
  }

  void _onClickStatus() async {
    int status = await BackgroundFetch.status;
    print('[BackgroundFetch] status: $status');
    setState(() {
      _status = status;
    });
  }

  void _onClickClear() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.remove(EVENTS_KEY);
    setState(() {
      _events = [];
    });
  }

  @override
  Widget build(BuildContext context) {
    const EMPTY_TEXT = Center(
        child: Text(
            'Waiting for fetch events.  Simulate one.\n [Android] \$ ./scripts/simulate-fetch\n [iOS] XCode->Debug->Simulate Background Fetch'));
    return MaterialApp(
      //*****************************************************************************************************************//
      //********************************************* I added this ******************************************************//
      //*****************************************************************************************************************//
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        // I added this
        splashColor: Colors.transparent,
        bottomSheetTheme: BottomSheetThemeData(
          backgroundColor: Colors.transparent,
        ),
      ),
      //*****************************************************************************************************************//
      //*****************************************************************************************************************//
      //*****************************************************************************************************************//
      home: Scaffold(
        //*****************************************************************************************************************//
        //********************************************* I added this ******************************************************//
        //*****************************************************************************************************************//
        resizeToAvoidBottomInset: false,
        backgroundColor: Colors.white,
        //*****************************************************************************************************************//
        //*****************************************************************************************************************//
        //*****************************************************************************************************************//
        appBar: AppBar(
            title: const Text('BackgroundFetch Example',
                style: TextStyle(color: Colors.black)),
            backgroundColor: Colors.amberAccent,
            brightness: Brightness.light,
            actions: <Widget>[
              Switch(value: _enabled, onChanged: _onClickEnable),
            ]),
        //*****************************************************************************************************************//
        //********************************************* I added this ******************************************************//
        //*****************************************************************************************************************//
        bottomSheet: Container(
          decoration: BoxDecoration(
            borderRadius: BorderRadius.only(
              topLeft: Radius.elliptical(30, 20),
              topRight: Radius.elliptical(30, 20),
            ),
            color: Colors.teal[300],
          ),
          child: TabBar(
              indicatorColor: Colors.teal[300],
              // indicatorWeight: 30,
              indicatorSize: TabBarIndicatorSize.label,
              controller: _tabController,
              labelPadding: EdgeInsets.all(0),
              indicatorPadding: EdgeInsets.all(0),
              enableFeedback: false,
              tabs: [
                Container(
                  decoration: BoxDecoration(
                    color: Colors.teal[300],
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.elliptical(30, 20),
                    ),
                  ),
                  width: mqPantalla.size.width / 3,
                  height: 55.9870,
                  child: MaterialButton(
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.only(
                      topLeft: Radius.elliptical(30, 20),
                    )),
                    highlightElevation: 0,
                    padding: EdgeInsets.all(0),
                    elevation: 0,
                    enableFeedback: false,
                    highlightColor: Colors.teal[100],
                    splashColor: Colors.transparent,
                    onPressed: () {
                      setState(() {});
                      _tabController.index = 0;
                    },
                    child: Icon(
                      Icons.home_outlined,
                      size: 30,
                      color: _tabController.index == 0
                          ? Colors.white
                          : Colors.black,
                    ),
                  ),
                ),
                Container(
                  decoration: BoxDecoration(
                    color: Colors.teal[300],
                  ),
                  width: mqPantalla.size.width / 3,
                  height: 55.987,
                  child: MaterialButton(
                    highlightElevation: 0,
                    padding: EdgeInsets.all(0),
                    elevation: 0,
                    enableFeedback: false,
                    highlightColor: Colors.teal[100],
                    splashColor: Colors.transparent,
                    onPressed: () async {
                      setState(() {});
                      _tabController.index = 1;
                    },
                    child: Icon(
                      Icons.dashboard_customize_outlined,
                      size: 30,
                      color: _tabController.index == 1
                          ? Colors.white
                          : Colors.black,
                    ),
                  ),
                ),
                Container(
                  decoration: BoxDecoration(
                    color: Colors.teal[300],
                    borderRadius: BorderRadius.only(
                      topRight: Radius.elliptical(30, 20),
                    ),
                  ),
                  width: mqPantalla.size.width / 3,
                  height: 55.987,
                  child: MaterialButton(
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.only(
                      topRight: Radius.elliptical(30, 20),
                    )),
                    highlightElevation: 0,
                    padding: EdgeInsets.all(0),
                    elevation: 0,
                    enableFeedback: false,
                    highlightColor: Colors.teal[100],
                    splashColor: Colors.transparent,
                    onPressed: () {
                      setState(() {});
                      _tabController.index = 2;
                    },
                    child: Icon(
                      Icons.trending_up,
                      size: 30,
                      color: _tabController.index == 2
                          ? Colors.white
                          : Colors.black,
                    ),
                  ),
                ),
              ]),
        ),
        //*****************************************************************************************************************//
        //*****************************************************************************************************************//
        //*****************************************************************************************************************//
        body: (_events.isEmpty)
            ? EMPTY_TEXT
            : Container(
                child: ListView.builder(
                    itemCount: _events.length,
                    itemBuilder: (BuildContext context, int index) {
                      List<String> event = _events[index].split("@");
                      return InputDecorator(
                          decoration: InputDecoration(
                              contentPadding: EdgeInsets.only(
                                  left: 5.0, top: 5.0, bottom: 5.0),
                              labelStyle:
                                  TextStyle(color: Colors.blue, fontSize: 20.0),
                              labelText: "[${event[0].toString()}]"),
                          child: Text(event[1],
                              style: TextStyle(
                                  color: Colors.black, fontSize: 16.0)));
                    }),
              ),
        bottomNavigationBar: BottomAppBar(
            child: Container(
                padding: EdgeInsets.only(left: 5.0, right: 5.0),
                child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      RaisedButton(
                          onPressed: _onClickStatus,
                          child: Text('Status: $_status')),
                      RaisedButton(
                          onPressed: _onClickClear, child: Text('Clear'))
                    ]))),
      ),
    );
  }
}

With these modifications the bottom Sheet sometimes does not load completely and this error happens.

Gcii commented 3 years ago

I was able to make the same look in the emulator when it fails on the physical cell phone. what I did is make the height and width that this function returns to be 0.

MediaQueryData mqPantalla = MediaQueryData.fromWindow(window);

// mqPantalla.size.height = 0 //mqPantalla.size.width= 0

this makes the app seemingly not loading because I use those measures in many widgets

I'll do tests with that.

Gcii commented 3 years ago

yes, I did tests on the xiaomi and it returns 0 in height and 0 in width. but it only happens when I use the backgroundfetch plugin and only a few times

christocracy commented 3 years ago

It sounds like you have a UI issue, not a plugin issue.