【问题标题】:How to continuously check internet connect or not on Flutter?如何在 Flutter 上持续检查互联网连接与否?
【发布时间】:2019-07-30 08:31:38
【问题描述】:

我使用此代码检查互联网。我也将此函数包装到 initState 中。当互联网不可用时,小吃栏始终显示。但是连接到互联网后,小吃店并没有消失。我不能使用连接插件,因为他们在 Android 上说,该插件不能保证连接到 Internet。

 checking1(TextEditingController usernameController, BuildContext context,
      String _url, GlobalKey<ScaffoldState> _scaffoldKey) async {
    try {
      final result = await InternetAddress.lookup('google.com');
      if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
        usernameController.text == '' ?
        showDialog(...some code...) :
        usernameValidation(usernameController.text, context, _url);
      }
    }
    on SocketException
    catch (_) {
      _showSnackBar(_scaffoldKey);
    }
  }

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    演示互联网连接及其来源的侦听器的完整示例。

    Original post

    import 'dart:async';
    import 'dart:io';
    import 'package:connectivity/connectivity.dart';
    import 'package:flutter/material.dart';
    
    void main() => runApp(MaterialApp(home: HomePage()));
    
    class HomePage extends StatefulWidget {
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      Map _source = {ConnectivityResult.none: false};
      MyConnectivity _connectivity = MyConnectivity.instance;
    
      @override
      void initState() {
        super.initState();
        _connectivity.initialise();
        _connectivity.myStream.listen((source) {
          setState(() => _source = source);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        String status = "Offline";
        switch (_source.keys.toList()[0]) {
          case ConnectivityResult.none:
            status = "Offline";
            break;
          case ConnectivityResult.mobile:
            status = "Mobile: Online";
            break;
          case ConnectivityResult.wifi:
            status = "WiFi: Online";
            break;
          case ConnectivityResult.ethernet:
            status = "Ethernet: Online";
            break;
        }
    
        return Scaffold(
          appBar: AppBar(title: Text("Internet")),
          body: Center(child: Text(status)),
        );
      }
    
      @override
      void dispose() {
        _connectivity.disposeStream();
        super.dispose();
      }
    }
    
    class MyConnectivity {
      MyConnectivity._internal();
    
      static final MyConnectivity _instance = MyConnectivity._internal();
    
      static MyConnectivity get instance => _instance;
    
      Connectivity connectivity = Connectivity();
    
      StreamController controller = StreamController.broadcast();
    
      Stream get myStream => controller.stream;
    
      void initialise() async {
        ConnectivityResult result = await connectivity.checkConnectivity();
        _checkStatus(result);
        connectivity.onConnectivityChanged.listen((result) {
          _checkStatus(result);
        });
      }
    
      void _checkStatus(ConnectivityResult result) async {
        bool isOnline = false;
        try {
          final result = await InternetAddress.lookup('example.com');
          if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
            isOnline = true;
          } else {
            isOnline = false;
          }
        } on SocketException catch (_) {
          isOnline = false;
        }
        controller.sink.add({result: isOnline});
      }
    
      void disposeStream() => controller.close();
    }
    

    【讨论】:

    • var 结果 = await Connectivity().checkConnectivity();给我类似“ConnectivityService:用户 11177 和当前进程都没有 android.permission.ACCESS_NETWORK_STATE.,null)”之类的错误有人可以帮忙吗?
    • @JayMungara 我无法得到部分错误,您是否已将ACCESS_NETWORK_STATE 权限添加到您的AndroidManifest.xml 文件中?
    • @JayMungara 如果您可以分享错误的屏幕截图会有所帮助。
    • @JayMungara 你运行了我的代码,它工作了吗?您看到其中有任何错误吗?如果是,我很乐意在 Stackoverflow 本身(不是 Github)上为您提供帮助,如果您可以提出问题并与我分享链接。
    【解决方案2】:

    另一个选项也可以是这个包:https://pub.dartlang.org/packages/flutter_offline,它处理这个问题非常简单。

    你需要先导入包'package:flutter_offline/flutter_offline.dart';

    之后,您在 Widget 构建(BuildContext 上下文)中包含 OfflineBuilder,它将连续读取 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),
                  ),
                  new Container(
                  ... 
                  ),
                ],
              ),
              floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
              drawer: MenuDrawer(),
            )
        );
      }
    

    【讨论】:

    • 这看起来不错,但我很困惑为什么必须有一个子属性而不是仅仅在构建器中返回小部件。这样,所有小部件都可以访问连接结果
    【解决方案3】:

    connectivity 包可以满足您的需求。它有一个您可以订阅的onConnectivityChanged 流。这将在连接状态更改时通知您的应用。但仅仅因为您的设备连接到网络并不意味着它可以访问您的服务器并连接。因此,在更新应用程序的内部状态之前进行 DNS 查找是一个好主意。

    https://pub.dartlang.org/documentation/connectivity/latest/connectivity/Connectivity-class.html

    【讨论】:

    • 这是唯一的选择吗?
    【解决方案4】:

    我认为这是可靠且更有说服力的:

    Future<bool> connectivityChecker() async {
      var connected = false;
      print("Checking internet...");
      try {
        final result = await InternetAddress.lookup('google.com');
        final result2 = await InternetAddress.lookup('facebook.com');
        final result3 = await InternetAddress.lookup('microsoft.com');
        if ((result.isNotEmpty && result[0].rawAddress.isNotEmpty) ||
            (result2.isNotEmpty && result2[0].rawAddress.isNotEmpty) ||
            (result3.isNotEmpty && result3[0].rawAddress.isNotEmpty)) {
          print('connected..');
          connected = true;
        } else {
          print("not connected from else..");
          connected = false;
        }
      } on SocketException catch (_) {
        print('not connected...');
        connected = false;
      }
      return connected;
    }
    

    根据返回的连接的布尔值,我会运行一个基于计时器的循环来再次检查互联网,直到它连接。接受任何建议

    【讨论】:

      猜你喜欢
      • 2023-01-13
      • 2022-11-05
      • 2020-04-17
      • 2019-07-27
      • 1970-01-01
      • 1970-01-01
      • 2022-12-01
      • 2019-09-03
      • 1970-01-01
      相关资源
      最近更新 更多