不断检查 Flutter 应用程序上的互联网断开连接

Posted

技术标签:

【中文标题】不断检查 Flutter 应用程序上的互联网断开连接【英文标题】:Continuously check internet disconnection on Flutter app 【发布时间】:2019-05-01 10:57:59 【问题描述】:

我正在 Flutter 上创建一个移动应用程序,并且我正在调用在 Node.js 上创建的 REST API,以便始终连接和查询我的 oracle DB。

到目前为止,我一直在使用 connectivity 0.3.2,以便在异步调用或登录操作之前检查网络连接。像下面的例子:

    checkConnectivity(context) async

  String connectionStatus;
  StreamSubscription<ConnectivityResult> _connectivitySubscription;
  final Connectivity _connectivity = new Connectivity();
  try 
    connectionStatus = (await _connectivity.checkConnectivity()).toString();
    _connectivity.onConnectivityChanged.listen((ConnectivityResult result) 
      connectionStatus = result.toString();
      //   print(connectionStatus);
    );
   on PlatformException catch (e) 
    print(e.toString());
    connectionStatus = 'Failed to get connectivity.';
  
  if(connectionStatus == "ConnectivityResult.none")
    components.alertPopup(context, "No Internet Connection available" , "Please check your internet connection and try again");


我想问是否有任何可能的方法可以在用户使用应用程序的每一刻持续检查互联网断开(即使他只是在读取数据,而无需在全部)。

例如为了通知用户他离线了一个 SnackBar。

【问题讨论】:

【参考方案1】:

您的 pubspec.yaml,将以下行添加为:

flutter_offline: "^0.3.0"

导入

import 'package:flutter_offline/flutter_offline.dart';

示例:

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
          appBar: AppBar(
            title: Text("Connection status"),
          ),
          body: Builder(
            builder: (BuildContext context) 
              return OfflineBuilder(
                connectivityBuilder: (BuildContext context,
                    ConnectivityResult connectivity, Widget child) 
                  final bool connected =
                      connectivity != ConnectivityResult.none;
                  return Stack(
                    fit: StackFit.expand,
                    children: [
                      child,
                      Positioned(
                        left: 0.0,
                        right: 0.0,
                        height: 32.0,
                        child: AnimatedContainer(
                          duration: const Duration(milliseconds: 300),
                          color:
                              connected ? Colors.green : Colors.red,
                          child: connected
                              ? Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: <Widget>[
                                    Text(
                                      "YOU ARE OFFLINE",
                                      style: TextStyle(color: Colors.white),
                                    ),
                                  ],
                                )
                              : Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: <Widget>[
                                    Text(
                                      "YOU ARE OFFLINE",
                                      style: TextStyle(color: Colors.white),
                                    ),
                                    SizedBox(
                                      width: 8.0,
                                    ),
                                    SizedBox(
                                      width: 12.0,
                                      height: 12.0,
                                      child: CircularProgressIndicator(
                                        strokeWidth: 2.0,
                                        valueColor:
                                            AlwaysStoppedAnimation<Color>(
                                                Colors.white),
                                      ),
                                    ),
                                  ],
                                ),
                        ),
                      ),
                    ],
                  );
                ,
                child: Center(
                  child: Text("ONLINE Or OFFLINE"),
                ),
              );
            ,
          )),
    );
  

【讨论】:

【参考方案2】:

我刚刚实现了这个包https://pub.dartlang.org/packages/flutter_offline,它非常简单地处理了这个问题。

第一步是导入包 导入'package:flutter_offline/flutter_offline.dart';

您包含在项目中并开始使用该库,如以下示例所示:

之后,您将 OfflineBuilder 包含在 Widget build(BuildContext context) 它会从 ConnectivityResult 读取所有流的变化,即使用户根本没有与应用程序交互(或只是读取数据)并且连接状态发生变化。

    @override
  Widget build(BuildContext context) 
    return OfflineBuilder(

        debounceDuration: Duration.zero,
        connectivityBuilder: (
            BuildContext context,
            ConnectivityResult connectivity,
            Widget child,
            ) 
          if (connectivity == ConnectivityResult.none) 

            return Scaffold(
              appBar: AppBar(
                title: const Text('Home'),
              ),
              body: Center(child: Text('Please check your internet connection!')),
            );
          
          return child;
        ,


        child: Scaffold(
          resizeToAvoidBottomPadding: false,
          appBar: AppBar(
              title: Text("Home")
          ),
          body: new Column(
            children: <Widget>[
              new Container(
                decoration: new BoxDecoration(color: Theme.of(context).cardColor),
                child: _buildTxtSearchBox(),
              ),
              new Divider(height: 10.0),
              new FloatingActionButton.extended(
                icon: Icon(Icons.camera_alt),
                label: Text("Barcode"),
                onPressed: _scanQR,
              ),
              new Container(
                // padding: EdgeInsets.only(left: 24.0, right: 24.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    Column(
                      children: [
                        Icon(Icons.hotel, color: Colors.blueGrey[600]),
                      ],
                    ),
                    Column(
                      children: [
                        Icon(Icons.hotel, color: Colors.blue[400]),
                      ],
                    ),
                  ],
                ),

                alignment: Alignment(0.0, 0.0),
              ),
            ],
          ),
          floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
          drawer: MenuDrawer(),
        )
    );
  

【讨论】:

但是先生,当互联网可用时,如果它离线,它会正确显示消息。但是当互联网不可用时,如果互联网可用,它不会返回孩子。你能在这里帮忙吗?谢谢你【参考方案3】:

您已经编写了代码来做您想做的事。您可以轻松地将其包装在页面 StateInheritedWidget 或其他一些管理类中。

final Connectivity _connectivity;
final StreamSubscription<ConnectivityResult> _subscription;

ConstructorForWhateverClassThisIs() 
    _connectivity = new Connectivity();
    _subscription = _connectivity.onConnectivityChanged.listen(onConnectivityChange);


void onConnectivityChange(ConnectivityResult result) 
    // TODO: Show snackbar, etc if no connectivity


void dispose() 
    // Always remember to cancel your subscriptions when you're done.
    subscription.cancel();

根据documentation,onConnectivityChanged 将在新结果发生更改时更新,这意味着您只需侦听更改而无需手动查询。

文档摘录:

您还可以通过订阅 连接插件公开的流

【讨论】:

是的,谢谢,这确实是迄今为止实现的内容,但是如果我没记错的话,或者至少在所有课程中听听 ConnectivityChanged想听连接变化。我在询问更多是否有任何可能的方法可以仅在应用程序的特定部分(例如入口点)内侦听和检查状态更改,并且在通知用户之后,即使他已经打开应用程序并且没有与应用程序交互根本没有,或者正在调用与我们正在监听连接更改的类不同的类。 在这种情况下,听起来你想要Redux。 Redux 将允许您从应用程序中的任何位置通知状态更改并让它们向下传播。更细化的选项可能是编写一个订阅事件流的InheritedWidget

以上是关于不断检查 Flutter 应用程序上的互联网断开连接的主要内容,如果未能解决你的问题,请参考以下文章

我需要一个事件来检测Internet连接/断开连接

如何在 Flutter 上持续检查互联网连接与否?

使用 QPython 连接到接入点?

Safari Web 检查器不断断开连接

我需要一个事件来检测 Internet 连接/断开连接

Flutter 如何检查我的设备是不是通过蓝牙连接到另一台设备