flutter didChangeAppLifecycleState never runs - flutter

I implemented the WidgetsBindingObserver, but the app is NEVER sent to the background so it doesn't recognize the AppLifecycleState.resumed
this is the current implementation
#override
void didChangeAppLifecycleState(AppLifecycleState state) async {
print('\n\ndidChangeAppLifecycleState');
switch (state) {
case AppLifecycleState.resumed:
print('\n\nresumed');
_mymethod();
break;
case AppLifecycleState.inactive:
print('\n\ninactive');
break;
case AppLifecycleState.paused:
print('\n\npaused');
break;
case AppLifecycleState.detached:
print('\n\ndetached');
break;
}
}
to simulate the process i do the next in android
run the project as --release
open the widget with the WidgetsBindingObserver
open another app (like chrome or phone settings)
return to the app
when returning to the app i can see my widget on screen, the app doesn't restart, but NONE of the prints appears on the console not event the print('\n\ndidChangeAppLifecycleState'); and _mymethod(); is never executed

The WidgetsBindingObserver mixin requires a bit more work than merely implementing the interface. You also need to add the following to your widget state class:
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}

Related

Call local_auth in flutter resume state will request authentication continuously

I'm using the local_auth package to lock app services after login if the user closes the app
what I want is to call the authentication function in the resume state of AppLifecycleState (when the user opens the app again)
but this prompt authentication infinitely
class _AppState extends State<App> with WidgetsBindingObserver {
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) async {
switch (state) {
case AppLifecycleState.inactive:
break;
case AppLifecycleState.paused:
break;
case AppLifecycleState.resumed:
{
await _auth.authenticate(
useErrorDialogs: true,
stickyAuth: true,
);
}
break;
case AppLifecycleState.detached:
break;
}
}
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
This will call authentication forever
how to solve this?

How can I detect share sheet open or closed in flutter programmatically

In my page, there is a share button by using this share package.
Share package
I want, when share sheet comes, the share button become hide, and when share sheet closed, share button wants to be show.. How can I implement this?
Why don't you add this?, Run this command: $ flutter pub add flutter_share
Like what's in here = https://pub.dev/packages/flutter_share/install
instead using share package use flutter_share and use blow code for your purpose.
await FlutterShare.share(title: ' ', text: ' ', linkUrl: your link, chooserTitle: your title).then((value){
//insert your code here for make btn disapeare
print('flutter share now is open') });
You may want to check Share.shareWithResult function which returns ShareResult object. This way you may detect if sheet was dismissed or a successful share took place.
Moreover, you may try WidgetsBindingObserver. When a share sheet is shown the app is in inactive state, when it is closed the app goes into resumed state.
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
const MyWidget({super.key});
#override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> with WidgetsBindingObserver {
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed:
print('sheet dismissed');
break;
case AppLifecycleState.inactive:
print('sheet shown');
break;
case AppLifecycleState.paused:
case AppLifecycleState.detached:
break;
}
}
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
#override
Widget build(BuildContext context) {
return Container();
}
}

Flutter | Stop music when minimised using audioplayers

In my app, I am playing music (local) in a loop, which plays continuously unless the user stops it. I am using audioplayers package.
Future playLoop(String filePath) async {
player.stop();
player = await cache.loop(filePath);
}
Currently, when app is minimised, the music is not getting stoped. The feature I want to implement is that when the app is minimised, it should stop playing music in the background.
Thanks in advance.
Solutions :
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.paused) {
//stop your audio player
}else{
print(state.toString());
}
}
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
There are mainly 4 states for it:
resumed: The application is visible and responding to user input.
inactive: The application is in an inactive state and is not receiving
user input.
paused: The application is not currently visible to the user, not
responding user input, and running in the background.
detached: The application is still hosted on a flutter engine but is
detached from any host views.
The solution above is correct, but some steps are needed before to get it
1 add WidgetsBindingObserver to your class
class AnyClass extends StatefulWidgets {
_AnyClassState createState() => _AnyClassState();
}
class _AnyClassState extends State<AnyClass> with
WidgetsBindingObserver {
Widget build(BuildContext context) {
return ...
}
}
2 Now it will work, we can added the methods inside class
class _AnyClassState extends State<AnyClass> with
WidgetsBindingObserver {
// ADD THIS AppLifecycleState VARIABLE
late AppLifecycleState appLifecycle;
// ADD THIS FUNCTION WITH A AppLifecycleState PARAMETER
didChangeAppLifecycleState(AppLifecycleState state) {
appLifecycle = state;
setStae(() {});
if(state == AppLifecycle.paused) {
// IF YOUT APP IS IN BACKGROUND...
// YOU CAN ADDED THE ACTION HERE
print('My app is in background');
}
}
// CREATE INITSTATE AND DISPOSE METHODS
initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
Widget build(BuildContext context) {
return ...
}
}
NOW IT WILL WORK FINE!

How does flutter handle mobile screen being turned off?

Only some Dart code runs when the screen is off. What does Flutter do when the mobile phone screen is turned off? Does it stop rendering but still runs specific Dart code?
In my case, Dart callback functions (passed to Flutter plugins) are called even when the screen is off. I want to customise/ control this behaviour, as I am running computational costly code that shouldn't run when the user can't see the output. I can already run code when the screen is turned off (such as by using screen_state flutter plugin or using ScreenStateObserver as provided by Miguel Ruivo, but it has limitations. I am not able to pop the route using Navigator.pop(). I also want to generally understand how Flutter is affected when the screen is off.
You want to take a look at WidgetsBindingObserver mixin as it will provide you with the different application lifecycle to your widget's state.
You'll then want to subscribe on initState()
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
and remove the listener on dispose()
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
and access the different states on didChangeAppLifecycleState()
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed:
print('app resumed');
break;
case AppLifecycleState.inactive:
print('app inactive');
break;
case AppLifecycleState.paused:
print('app paused');
break;
case AppLifecycleState.detached:
print('app deatched');
break;
}
}

How to show an alert when user is trying to go in background mode?

I want to show a simple alert dialog box when user push an app to background and ask something like Are you sure? before losing all the important information on that page. I am using multi-screen form to get user data and don't want to break the flow so a simple message would help.
I am trying to achieve this with WidgetsBindingObserver and AppLifecycleState but it doesn't seem to work.
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
#override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
switch (state) {
case AppLifecycleState.paused:
print('paused');
AlertDialog(
title: Text('Are you sure?'),
);
break;
default:
break;
}
}
Paused is getting print so the functionality is working fine, now I need some way to restrict this with Alert Dialog box or any other way.