How to run some dart code in the background, every 15 seconds - flutter

I've created app that checks the call log list every 15 seconds. I have used Timer.periodic() to achieve this. And everything works fine but only if app is not running in the background. After couple of minutes when app is in the background, the task which is scheduled by Timer.periodic is not executing anymore. I have tried to use android_alarm_manager https://pub.dev/packages/android_alarm_manager but it doesn't work at all. It's logging /FlutterBackgroundExecutor(11431): Starting AlarmService... but then nothing happends.
import 'dart:isolate';
import 'package:flutter/material.dart';
import 'package:android_alarm_manager/android_alarm_manager.dart';
void main() async{
await WidgetsFlutterBinding.ensureInitialized();
await AndroidAlarmManager.initialize();
runApp(MyApp());
final int helloAlarmID = 0;
await AndroidAlarmManager.periodic(Duration(seconds: 5), helloAlarmID, printHello);
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
void printHello() {
final DateTime now = DateTime.now();
final int isolateId = Isolate.current.hashCode;
print("[$now] Hello, world! isolate=${isolateId} function='$printHello'");
}
Do I have any other possibilities to reach my goal ?

Android limits background usage to every 15 minutes or so. There are several packages on pub.dev that can run code in background even when the application is closed. However i don't think any of them can run your code every 15 seconds.
Packages include:
background_fetch
workmanager
flutter_background_service
There are several more.

Related

How to check if it's the first time a user launches an app using is_first_run library?

I tried using the is_first_run package to check if it's the first time my app has been launched. It actually worked as intended the first time I ever tested it. It took the user to the Welcome page on first launch, and then subsequent launches went to the Sign up or Log in page. But any efforts to recreate it again to make sure it's working have failed, and instead it takes me straight to Sign up or Log in, even after uninstalling the app from my device, running flutter clean, deleting all cache and storage for the app, and testing it on a completely different device. Any reason why it's not working anymore?
Here is the entire code for my main file:
import 'package:screens/welcomepages/signup_or_login.dart';
import 'package:screens/welcomepages/welcome.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:config/theme.dart';
import 'package:is_first_run/is_first_run.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarBrightness: Brightness.dark));
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
var ifr = _checkFirstRun();
if (ifr == true) {
return MaterialApp(
theme: theme(),
debugShowCheckedModeBanner: false,
home: const Welcome(),
);
}
return MaterialApp(
theme: theme(),
debugShowCheckedModeBanner: false,
home: const SignUpOrLogIn(),
);
}
}
Future<bool> _checkFirstRun() async {
return await IsFirstRun.isFirstRun();
}
Any alternative solutions also welcome.
I think you should use Shared preferences for better state management.
However, with this library, you can try the reset() function.
After calling reset(), calling isFirstRun() will return true as long as the app is running. After a restart, it will return false again. The first call of isFirstCall() will return true, subsequent calls will return false again.

Looking for advice on implementing state to add/delete from a ListView

I am attempting to make my first app after numerous videos and courses. I have no prior experience in programming before this. Dart/Flutter is my first language and I am having trouble finishing the last steps on my app.
My first attempt I was able to add and delete stocks from the ListView.builder but I could not get the data from the api to work properly.
I figured out how to use the api the way I needed to but I couldn't get it to work with the way the app was built. So I completely redid the app to work with the api data, but now I cannot figure out how to add stocks with the TextField and remove them with Dismissible.
I hate to ask for help because I am trying to teach myself as I got but I have been stuck for 2 weeks since the ui was built. I've watched many videos and asked questions on Stack with no luck.
If anyone could show me how to implement the state management it would be greatly appreciated!
https://github.com/romajc84/my_stock_app.git
I checked the codebase, first of all great work for a starter! I have wrote few notes (I don't have the time to write a lot of things but you have to focus on architecture more).
The dismissing functionality is done with simple Dismissible widget.
I hate to ask for help because I am trying to teach myself as I got but I have been stuck for 2 weeks since the ui was built.
Don't hate to ask ^_^. It's okay to ask, but your question should be focused and specific. You shouldn't expect people to search in your repo and fix your bugs. You have to show the code snippet you have question about, what you have tried, what you expect and what you get instead.
And try to keep it one specific question per post.
This way you will get the help you want.
I only implemented the adding mechanism using ChangeNotifier like so:
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'http_etf.dart';
import 'http_stock.dart';
class ProvModel extends ChangeNotifier {
static const _defaultSymbols = ['t', 'aapl', 'tsla', 'amd', 'googl', 'spy'];
final List<Stock> _symbols = [];
final List<Etf> _etf = [];
bool _adding = false;
void fetchData() async {
_fetchEtf().catchError(print);
_fetchStocks().catchError(print);
}
Future<void> _fetchStocks() async {
final stocks = await fetchStocks(_defaultSymbols, Client());
_symbols.addAll(stocks);
notifyListeners();
}
Future<void> _fetchEtf() async {
final etf = await fetchEtf(Client());
_etf.addAll(etf);
notifyListeners();
}
UnmodifiableListView<Stock> get symbols => UnmodifiableListView(_symbols);
UnmodifiableListView<Etf> get etf => UnmodifiableListView(_etf);
bool get adding => _adding;
void addSymbol(String newSymbol) async {
_adding = true;
notifyListeners();
final stocks = await fetchStocks([newSymbol], Client());
if (stocks == null || stocks.isEmpty) return;
final stock = stocks.first;
_symbols.add(stock);
_adding = false;
notifyListeners();
}
}
I created a method dedicated to work once the app starts to start fetching the data for both the stocks and the etf, in the MyApp as following:
import 'package:flutter/material.dart';
import 'package:my_stock_app/prov_model.dart';
import 'package:provider/provider.dart';
import 'home_page.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => ProvModel()..fetchData(),
child: MaterialApp(
theme: ThemeData(
primaryColor: Colors.black,
textTheme: TextTheme(
bodyText2: TextStyle(
color: Colors.white,
),
),
),
home: HomePage(),
),
);
}
}
I tried to refactor the code a bit.
Here's the functioning project: Repository
Keep it up and keep learning!

How to bring an app from background to foreground in flutter

I have an app that is managing audio calls. When a call is made to the add and the app is running in the background I need to bring the app in the foreground state. I tried to use Navigator. push but without any result.
You can use the package bringtoforeground. It's fairly in the early stages with respect to its version but it works.
iOS
But this only works on android, you have to keep in mind that iOS apps that are on the background are destroyed. you can read this do
see details here
Android
So this implementation will only work on Android.
The best thing with this package is that you can use it with Firebase Cloud Messaging (FCM) or any other for that matter.
This is their example, Bringtoforeground.bringAppToForeground(); this is the piece of code you use to bring your app to the foreground.
import 'dart:async';
import 'package:bringtoforeground/bringtoforeground.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
#override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
Timer.periodic(Duration(seconds: 10), (t) {
Bringtoforeground.bringAppToForeground(); //This is the only thing that matters
});
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// 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;
setState(() {
_platformVersion = platformVersion;
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Text('Running on: $_platformVersion\n'),
),
),
);
}
}
Install flutter_foreground_task package here is
and use FlutterForegroundTask.minimizeApp() for app to background
and use FlutterForegroundTask.launchApp() for app to foreground that's all.
I think it helps.
if you work with flutter_local_notifications package
you can add this argument to AndroidNotificationAction
from here
hope this help (:

How to create a scheduled service in Flutter

How can you create a scheduled service in Flutter, which will be triggered at a specific time every day, and it will run some code? It needs to work for both Android and IOS and even if the app is terminated.
You could make use of the alarm manager package.
A simple implementation of the same would look like below.
import 'dart:async';
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'package:flutter/widgets.dart';
void doStuff() {
print("do stuff every minute");
}
Future<void> main() async {
final int periodicID = 0;
// Start the AlarmManager service.
await AndroidAlarmManager.initialize();
runApp(const Center(
child:
Text('See device log for output', textDirection: TextDirection.ltr)));
await AndroidAlarmManager.periodic(
const Duration(minutes: 1), periodicID, doStuff,
wakeup: true);
}

How to keep application awake in flutter?

How to keep an application from locking the screen in flutter?
Is there a flag to turn it off an on? Does flutter SDK expose this?
Something like keepAwake(true);
As support for the screen plugin that #Tree mentioned has been discontinued and there are some issues with it now, you can use wakelock.
Full disclosure: I am the author of this plugin, however, it is basically a port of the wakelock functionality from the screen plugin, with the issues fixed:
import 'package:wakelock/wakelock.dart';
// To keep the screen on:
Wakelock.enable(); // or Wakelock.toggle(on: true);
// To let the screen turn off again:
Wakelock.disable(); // or Wakelock.toggle(on: false);
Learn more.
I found plugin that does the job.
https://pub.dartlang.org/packages/screen
import 'package:screen/screen.dart';
// Prevent screen from going into sleep mode:
Screen.keepOn(true);
You also need to set permission for android
<uses-permission android:name="android.permission.WAKE_LOCK" />
This package does the work
https://pub.dev/packages/wakelock
It depends on Flutter Wakelock class.
Permissions
The wakelock plugin does not require any permissions on any platform.
This is because it only enables the screen wakelock and not any partial (CPU) wakelocks that would keep the app alive in the background.
How to Use it?
// to enable the Android and iOS wakelock
Wakelock.enable();
// to disables the wakelock again.
Wakelock.disable();
import 'package:flutter/material.dart';
import 'package:wakelock/wakelock.dart';
void main() {
runApp( MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
Wakelock.enable(); // Here :)
return MaterialApp(
home: MyHomePage(),
);
}
}
Note: You have to Stop and Run again
As #creativecreatorormaybenot already answered, you can use wakeLock to keep the screen on. But I wanted to add where to put the Wakelock.enable();.
Here a code snippet how I used it and it works fine for me:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
Wakelock.enable();
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MainScreen()
);
}
}
I hope it will fix your problem. Here is the link to the package: https://pub.dev/packages/wakelock