I am building kind of an android chat app and I want to ask how I could build up a background thread that checks for incoming messages (from a rest api). My current solution is a JobService but I expect it to have a high battery consumption. Also the JobService has another problem: After closing the app it takes about 3 minutes to get started again (I want it all the time:)
I prefer to not use firebase btw
Thank you very much in advance.
I would like an app to open a dialog box every day at 2pm, even if the user is doing something else and is not currently in the app interface at this time.
How to do this with Flutter, such that it will work both on Android and iOS?
I was thinking about a method like this:
timer = Timer.periodic(Duration(seconds: 60), (Timer t) => checkTime());
that checks every minute if it's between 14:00:00 and 14:00:59, with a method similar to
flutter run function every x amount of seconds, but this seems like a waste of resource: there is probably better, with a more natural way to wake up an app in the background at a precise timing?
Question: how to make an app display a dialog box at 2pm every day, even if the user is doing something else/is in another app, with Flutter?
Note: if the device has its screen off (i.e. user is not using their phone), the dialog box should be displayed the next time the screen is turned on.
My solution would be using the workmanager (Current version 0.4.1) flutter package to achieve the requirement you are looking for. Since it is maintained by Flutter Community team , we can expect a long term support.
Based on their documentation
Flutter WorkManager is a wrapper around Android's WorkManager and iOS' performFetchWithCompletionHandler, effectively enabling headless
execution of Dart code in the background.
This is especially useful to run periodic tasks, such as fetching remote data on a regular basis.
Android work manager will automatically handles the background processes by itself based on the OS level of version it is running.
And coming to iOS, based on their doc the feature that this package use to perform background operation is deprecated. But Flutter community team is ready to push the replacement in the upcoming release as per their comment in the GitHub repo. So upgrading to the latest version will help you to solve this issue.
Initialize the wrokmanager inside the main()
Workmanager().initialize(
callbackDispatcher, // The top level function, aka callbackDispatcher
isInDebugMode:
true // If enabled it will post a notification whenever the task is running. Handy for debugging tasks
);
and then schedule the task like below
Workmanager().registerOneOffTask("1", "simpleTask_1",
initialDelay: Duration(seconds: 15));
Workmanager().registerPeriodicTask("102", "simplePeriodicTask_1",
initialDelay: Duration(seconds: 15),
frequency: Duration(minutes: 15)); // Set your 2 PM frequency here.
Refer documentation and setup for available options on scheduling tasks.
And define a callbackDispatcher and it needs to be either a static function or a top level function to be accessible as a Flutter entry point as per the documentation.
//Defined outside main()
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) {
print(
"Native called background task: callbackDispatcher"); //simpleTask will be emitted here.
createNotify(); // Created a local notification to make sure everything works in background - In your case show alert here.
return Future.value(true);
});
}
// your main() goes here
Instead of displaying notification, derive your logic down to show the alert popup.
EDIT 1 :
To answer your questions in comments
How do you check the program only runs once per day at around 14:00:00
PM?
Scheduled work is stored in an internally managed SQLite database and WorkManager takes care of ensuring that this work persists and is rescheduled across device reboots. And this will be executed multiple times until it is cancelled manually.
Apart from this for dev purpose you can set minimum interval and verify like 1 hour once. And minimum supported interval for work manager is 15 minutes. Even if you set below that threshold time, 15 minutes is set as default.
It seems that your code does a periodic run but it doesn't run at a
specific time.
This is not supported out of the box till now. But we can make use of initial delay while scheduling the task. Calculate the time difference between present time and time you want to trigger.
For example , if I want to schedule some task at 9'o clock and when the scheduling the task you can do the following
When app is opened at 7'o clock , then set the initial delay as two hours.
Refer the stackoverflow answer related to this.
Also, with this method, are you sure it won't be automatically closed
by the OS for battery saving?
According to WorkManager doc, the execution will happen during the period interval that we specify. Since WorkManager is subject to OS battery optimizations, such as doze mode we need to note that execution may be delayed but not cancelled.
Last thing: can a background process start a popup without user
interaction? (other answers mention it's not really possible). Thanks
again!
For me this is the tricky part. Technically, we cannot able to show UI without user actions from the background. Because, UI needs context based on which is shown to user. So coming to dart point, it may be hard to show some alert popup that you are seeking for. But if you just want to show only some sort of information, you can give it a try to FlutterToast as it will be shown to the user from background.
EDIT 2
The requirement that you are seeking to display alert during, when app is not open is called as Draw over other apps and it works only in Android as far as I guess since there is no such feature in iOS.
You can refer this package in flutter for showing alert as per your requirements. Combine the WorkManager with this package implementation to achieve your desired result. I have not tried with this package but let me know if you face any issues.
Happy Coding !!
TL,DR: Use alarm_manager_service. It can schedule tasks for a particular time, and if needed, have it repeat after set duration from that start time.
You were planning to have the full code in the main app. The problem is, there is no guarantee that the app will not be closed by Android OS. With, power management features (doze), the app will likely be killed in hours. Recent android versions give users explicit control. The user will have to excuse this app from power optimizations(disable battery optimization). Even so, RAM management can kill the app in critical situations. This is expected behaviour.
Now, about displaying an interface to foreground: Android also seems to discourage intrusive app behaviours like bringing an activity to the foreground that obstructs the user while he is interacting with another activity. See https://developer.android.com/guide/components/activities/background-starts. It also lists exceptions, whereby you can achieve this. (I know Facebook/messenger used to do this and all sorts of background activities even after killing tasks without respect for recommendations. But then most of us hate FB apps for being too intrusive, and have given me an unethical impression).
Running the app continuously only to check for a particular time of day is certainly waste of resource.
So you will have to register a background service apart from the main GUI app code. Dart apps run as isolates. You can create a separate isolate for the background service apart from the main GUI that the user interacts with. Now, even if the main GUI isolate is closed, the background service can run.
You'll need to modify android manifest file also when doing these. I can point you to some leads:
Use an alarm_manager_service to schedule background tasks at the set time.This can then callback to carry out activity and show a dialog box or wake the app.
Another one: workmanager
Read this quick and to the point summary given as the readme description to understand the existing scenario in android OS. This actually sums up everything that I read through countless developer.android articles.
SAMPLE CODES:
You can use alarm manager to schedule tasks for a particular time, and also have it repeat after set duration from the start time ~> start at 2pm some day and repeat it periodically every 24 hours.
The codes for using alarm_manager is given here as answer (Solution1).
I had a similar requirement, and it's a very difficult thing to do with the requirement of drawing over other apps.
But I found an acceptable solution using the flutter_local_notifications package. You can schedule a periodic notification, and you can enable "fullScreenIntent". This link should help: https://pub.dev/packages/flutter_local_notifications#full-screen-intent-notifications
It's not perfect, but for perfect you would have to write native code using PlatformChannels:
https://flutter.dev/docs/development/platform-integration/platform-channels
If you aim to automatically open the App for an iOS-device-user. well, that's not possible. I'm not sure if it is possible for Android as well.
You may want to create a notification to push at 14:00 to ask the user if they want to open the dialog.
Here's the documentation link for Notifications in FlutterFire: Notifications
and Documentation for widgets with Flutter (You'll need Xcode for this): Develop an iOS 14 Widget in Flutter with SwiftUI
I am devolping an Android App that need to execute an accumulation of internet tasks periodically (like a web bot). Those tasks need to get stored at a specific time so I thought about using Alarm Manager and a
embeded Database. Due to it, the app could be active much more time, although those save tasks do not need web connection. Later I will throw another Alarm Manager to execute all the tasks queued and do web stuff.
Otherwise I am not sure if it is better to use a foreground service. The app will be working all the day saving the tasks (each 5 or 15 min) but only running task queue with internet each 30mins.
I feel capable of developing both systems but I would like to know which one is better in terms of performance, of battery consumption.
Thank you very much.
Only a recommendation try to find and use a nice library to do it, every Android Update change something about foreground/background servicess.
one is
TimedDog
and for more
enter link description here
I'm writing an app with flutter to communicate with a weather station. The smartphone/tablet have to send via usb a command every one minute, recieve data from the station, and then send this data in a Firebase database.
I know that a smartphone is not the best device for do this, but I'm using an old device and I don't care about battery health (maybe a raspberry could be a better solution).
I'm using usb_serial package to communicate via usb and cron package for timing the events. And all works fine.
The problem is that the app have always to run in foreground. The first solution that i tried is using two apps: (1) one that keeps the screen on (2) and another that makes the screen black to reduce the energy consumpion. This is not the best solution.
I think that a better way is to use a background execution. I made some attempts with workmanager package but the minimum frequency is 15 min, with android alarm manager package but I'm not sure that wakes up also the network connection.
Anybody can suggest me witch is the best way to achieve my goal?
Thanks.
Refer this answer https://stackoverflow.com/a/14946013/13892187
In Dart for setting a recurring function we use the Timer class
I want to do an Android app that submits data to a web server. This application needs to run offline and the hour of the submitted info is crutial. We can't rely on the hour provided by the client, so we are always setting it in the server side. But, when android app goes offline, we need to keep a private clock separated from the system hour (because it can be modified by the user). My question is how can i achieve this? The first solution that cames to my mind is to keep a private clock in our app, but this is going to crash when someone closes it or when shutdown occurs. There is something done to achieve this in Android? Also, we are going to use Ionic framework (suggestions accepted ;))
Thanks.
You can achieve that by using SystemClock.
It allow you to know the time elapsed from the System startup.
Store the server timestamp and wake up you're app with AlarmService. Then check if the elapsed time is correct.