如何检查Flutter应用程序是否在前台?

Abc*_*Xyz 7 dart flutter

我不想在前台应用程序时显示通知。如何查看我的应用程序的实时状态?

cru*_*man 50

要扩展@CopsOnRoad 的回答,您可以使用一个switch语句使其美观整洁:

@override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        print("app in resumed");
        break;
      case AppLifecycleState.inactive:
        print("app in inactive");
        break;
      case AppLifecycleState.paused:
        print("app in paused");
        break;
      case AppLifecycleState.detached:
        print("app in detached");
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不要单独复制粘贴这个答案 - 它补充了另一个答案,正如它所说的那样 - 除非你也有: ```@override initState() { super.initState(); ,否则这将不起作用。WidgetsBinding.instance.addObserver(this); ... } @override void dispose() { WidgetsBinding.instance.removeObserver(this); 超级.dispose(); }``` (4认同)
  • 你忘了最后关闭大括号。请更新答案。谢谢。 (3认同)

Omi*_*aha 30

有一个名为 flutter_fgbg的包 用于此目的。

例子:

FGBGNotifier(
    onEvent: (event) {
        print(event); // FGBGType.foreground or FGBGType.background
    },
    child: ...,
)
Run Code Online (Sandbox Code Playgroud)

或者:

subscription = FGBGEvents.stream.listen((event) {
    print(event); // FGBGType.foreground or FGBGType.background
});

// in dispose
subscription.cancel();

Run Code Online (Sandbox Code Playgroud)

为什么

Flutter 具有 WidgetsBindingObserver,当应用程序将其状态从活动状态更改为非活动状态并返回时,它会收到通知。但它实际上还包括嵌入 Activity/ViewController 的状态更改。因此,如果您有一个插件可以打开新的活动/视图控制器(例如:图像选择器),或者在 iOS 中如果您启动 FaceID 提示,则 WidgetsBindingObserver 将报告应用程序处于非活动/恢复状态。

另一方面,该插件仅在应用程序级别报告事件。由于大多数应用程序只需要后台/前台事件,因此该插件仅使用这些事件来实现。在 iOS 中,插件报告 didEnterBackgroundNotification 和 willEnterForegroundNotification 通知,在 Android 中,插件使用 androidx.lifecycle:lifecycle-process 包报告这些通知。

查看示例/项目以了解操作上的差异。

示例链接

  • 这个答案应该有更多的赞成票。该死的不活动/暂停的 BS 导致了许多意想不到的错误。这应该总是像这个插件提供的那样简单。事实上,像这样的简单问题你需要一个插件,这就是外星文明仍然避开地球的原因。 (12认同)
  • 当我有多个屏幕时如何使用它?该插件无法获取另一个屏幕上的状态,即使使用示例应用程序,我也无法导航到下一个屏幕,我收到此错误抛出另一个异常:请求的导航器操作不包含航海家。 (2认同)

Cop*_*oad 17

只需创建一个bool变量来跟踪您的所有背景/前景内容。

完整代码:

class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
  // This variable will tell you whether the application is in foreground or not. 
  bool _isInForeground = true;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }
  
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    _isInForeground = state == AppLifecycleState.resumed;
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => Scaffold();
}
Run Code Online (Sandbox Code Playgroud)


Avi*_*ash 13

class YourClassState extends State<YourClass> with WidgetsBindingObserver{


  @override
  void initState(){
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }


  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        print("app in resumed");
        break;
      case AppLifecycleState.inactive:
        print("app in inactive");
        break;
      case AppLifecycleState.paused:
        print("app in paused");
        break;
      case AppLifecycleState.detached:
        print("app in detached");
        break;
    }
  }

}
Run Code Online (Sandbox Code Playgroud)


Val*_*ova 11

在您的State <...>类中,您需要实现WidgetsBindingObserver接口并侦听小部件状态更改。像这样:

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
  AppLifecycleState _notification; 
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    setState(() {
      _notification = state;
    });
  }

  @override
  initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    ...
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,当您想知道什么状态时,请检查_notification.index属性。_notification == null =>未发生状态更改,0-恢复,1-非活动,2-暂停。

  • 我是否需要在所有屏幕小部件类中添加 WidgetsBindingObserver,还是仅在附加到主类的小部件中添加 WidgetsBindingObserver? (2认同)
  • 您也可以随时使用枚举(推荐)AppLifecycleState.resumed 例如 (2认同)

小智 10

People have already posted the answer but this answer is for developers using Getx architecture. You will be able to use the same approach but instead of using it on our stateless widget use it in the controller page. This method helps you to manage foreground and background activities when using Getx state management architecture

class QuotesController extends GetxController  with WidgetsBindingObserver{

     @override
      void onInit() async{
        super.onInit();
        WidgetsBinding.instance?.addObserver(this);
     }
    
     @override
      void onClose() {
        WidgetsBinding.instance?.removeObserver(this);
      }
    
      @override
      void didChangeAppLifecycleState(AppLifecycleState state) async{
          switch(state){
    
            case AppLifecycleState.resumed:
              await player.play();
              break;
            case AppLifecycleState.inactive:
              await player.stop();
              break;
            case AppLifecycleState.paused:
              await player.stop();
              break;
            case AppLifecycleState.detached:
              await player.stop();
              // TODO: Handle this case.
              break;
          }
      }
    
    }
Run Code Online (Sandbox Code Playgroud)


ged*_*lod 6

我一直在寻找一种简单的方法来实现该解决方案,这是适合我的方法:

1.创建LifecycleEventHandler类

在此类中添加两个回调作为属性,suspendingCallBack当应用程序转到后台时将调用 ,resumeCallBack当应用程序返回前台时将调用 。

class LifecycleEventHandler extends WidgetsBindingObserver {
  final AsyncCallback resumeCallBack;
  final AsyncCallback suspendingCallBack;

  LifecycleEventHandler({
    required this.resumeCallBack,
    required this.suspendingCallBack,
  });

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    print('state >>>>>>>>>>>>>>>>>>>>>> : ${state}');
    switch (state) {
      case AppLifecycleState.resumed:
        if (resumeCallBack != null) {
          await resumeCallBack();
        }
        break;
      case AppLifecycleState.inactive:
      case AppLifecycleState.paused:
      case AppLifecycleState.detached:
        if (suspendingCallBack != null) {
          await suspendingCallBack();
        }
        break;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

2. 聆听状态变化。

在我们应用程序的主页中,我们可以创建一个变量来保存生命周期状态,当应用程序进入时background我们将值设置为true,否则该值将为false

class MainPageState extends State<MainPage> {

  bool isAppInactive = false; // if the app is Inactive do some thing

  @override
  initState(){
    super.initState();
    
    WidgetsBinding.instance.addObserver(
        LifecycleEventHandler(
            resumeCallBack: () async {
            // The app is now resumed, so let's change the value to false
            setState(() {isAppInactive = false; });
              
        }, suspendingCallBack: () async {
            // The app is now inactive, so let's change the value to true
            setState(() {isAppInactive = true; });
        })
    );

  }

}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用该变量值来做你想做的事

if(isAppInactive){
  // then do some thing
}
Run Code Online (Sandbox Code Playgroud)


无夜之*_*之星辰 5

您可以使用全局变量来保存状态以方便使用。

例如:

1.创建全局变量:

AppLifecycleState appLifecycleState = AppLifecycleState.detached;
Run Code Online (Sandbox Code Playgroud)

2. 在你的AppState类中添加Observer:

AppLifecycleState appLifecycleState = AppLifecycleState.detached;
Run Code Online (Sandbox Code Playgroud)

3.保存状态:

@override
void initState() {
  super.initState();
  WidgetsBinding.instance?.addObserver(this);
}

@override
void dispose() {
  WidgetsBinding.instance?.removeObserver(this);
  super.dispose();
}
Run Code Online (Sandbox Code Playgroud)

4. 现在您可以在任何需要的地方轻松使用它:

if (appLifecycleState == AppLifecycleState.paused) {
  // in background
}
Run Code Online (Sandbox Code Playgroud)