Closed Gcii closed 3 years ago
You must not ignore the issue template.
Your Environment
flutter info
, flutter doctor
):To Reproduce Steps to reproduce the behavior:
Debug logs
$ adb logcat
Additional context Add any other context about the problem here.
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.
Please learn how to Syntax Highlight Code Blocks.
Edit your issue.
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
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
.
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.
I don't know how to get $ adb logcat. of the physical device.
$ adb logcat
.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
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.
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
I suggest you install the /example app In this repo. Do not look at the code, just install it on your device.
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.
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.
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
It sounds like you have a UI issue, not a plugin issue.
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.