我有一个网络调用要执行。但在此之前,我需要检查设备是否有互联网连接。

这是我目前为止所做的:

  var connectivityResult = new Connectivity().checkConnectivity();// User defined class
    if (connectivityResult == ConnectivityResult.mobile ||
        connectivityResult == ConnectivityResult.wifi) {*/
    this.getData();
    } else {
      neverSatisfied();
    }

上述方法行不通。


当前回答

这是我的解决方案,它检查互联网连接以及数据连接,我希望你喜欢它。

First of all add dependencies in your pubsec.yaml
dependencies:        
    data_connection_checker:
And Here Is The main.dart Of My Solution
import 'dart:async';

import 'package:data_connection_checker/data_connection_checker.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Data Connection Checker",
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  StreamSubscription<DataConnectionStatus> listener;

  var Internetstatus = "Unknown";

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
//    _updateConnectionStatus();
      CheckInternet();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    listener.cancel();
    super.dispose();
  }

  CheckInternet() async {
    // Simple check to see if we have internet
    print("The statement 'this machine is connected to the Internet' is: ");
    print(await DataConnectionChecker().hasConnection);
    // returns a bool

    // We can also get an enum instead of a bool
    print("Current status: ${await DataConnectionChecker().connectionStatus}");
    // prints either DataConnectionStatus.connected
    // or DataConnectionStatus.disconnected

    // This returns the last results from the last call
    // to either hasConnection or connectionStatus
    print("Last results: ${DataConnectionChecker().lastTryResults}");

    // actively listen for status updates
    listener = DataConnectionChecker().onStatusChange.listen((status) {
      switch (status) {
        case DataConnectionStatus.connected:
          Internetstatus="Connectd TO THe Internet";
          print('Data connection is available.');
          setState(() {

          });
          break;
        case DataConnectionStatus.disconnected:
          Internetstatus="No Data Connection";
          print('You are disconnected from the internet.');
          setState(() {

          });
          break;
      }
    });

    // close listener after 30 seconds, so the program doesn't run forever
//    await Future.delayed(Duration(seconds: 30));
//    await listener.cancel();
    return await await DataConnectionChecker().connectionStatus;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Data Connection Checker"),
      ),
      body: Container(
        child: Center(
          child: Text("$Internetstatus"),
        ),
      ),
    );
  }
}

其他回答

我写了一个包来检查活跃的互联网连接和显示相应的小部件。

flutter_no_internet_widget

例子:

InternetWidget(
 online: Text('Online'),
 offline: Text('Offline),
);

根据网络状态,将显示适当的小部件。如果您有一个活跃的互联网连接,一个在线小部件将显示。

所有重量级的工作都由包完成,您所要做的就是提供在线和离线小部件。您还可以提供一个加载小部件和查找URL。

欢迎讨论、提交意见书或提出建议。

我有一个问题与提出的解决方案,使用查找并不总是返回预期的值。

这是由于DNS缓存,调用的值被缓存,而不是在下一次尝试时进行正确的调用,它会返回缓存的值。当然,这是一个问题,因为这意味着如果你失去了连接和调用查找,它仍然可以返回缓存的值,就像你有互联网一样,相反,如果你重新连接你的互联网后,查找返回null,它仍然会在缓存的持续时间内返回null,这可能是几分钟,即使你现在有互联网。

查找返回一些东西并不一定意味着你有网络,它不返回任何东西并不一定意味着你没有网络。它不可靠。

我从data_connection_checker插件中获得灵感,实现了以下解决方案:

 /// If any of the pings returns true then you have internet (for sure). If none do, you probably don't.
  Future<bool> _checkInternetAccess() {
    /// We use a mix of IPV4 and IPV6 here in case some networks only accept one of the types.
    /// Only tested with an IPV4 only network so far (I don't have access to an IPV6 network).
    final List<InternetAddress> dnss = [
      InternetAddress('8.8.8.8', type: InternetAddressType.IPv4), // Google
      InternetAddress('2001:4860:4860::8888', type: InternetAddressType.IPv6), // Google
      InternetAddress('1.1.1.1', type: InternetAddressType.IPv4), // CloudFlare
      InternetAddress('2606:4700:4700::1111', type: InternetAddressType.IPv6), // CloudFlare
      InternetAddress('208.67.222.222', type: InternetAddressType.IPv4), // OpenDNS
      InternetAddress('2620:0:ccc::2', type: InternetAddressType.IPv6), // OpenDNS
      InternetAddress('180.76.76.76', type: InternetAddressType.IPv4), // Baidu
      InternetAddress('2400:da00::6666', type: InternetAddressType.IPv6), // Baidu
    ];

    final Completer<bool> completer = Completer<bool>();

    int callsReturned = 0;
    void onCallReturned(bool isAlive) {
      if (completer.isCompleted) return;

      if (isAlive) {
        completer.complete(true);
      } else {
        callsReturned++;
        if (callsReturned >= dnss.length) {
          completer.complete(false);
        }
      }
    }

    dnss.forEach((dns) => _pingDns(dns).then(onCallReturned));

    return completer.future;
  }

  Future<bool> _pingDns(InternetAddress dnsAddress) async {
    const int dnsPort = 53;
    const Duration timeout = Duration(seconds: 3);

    Socket socket;
    try {
      socket = await Socket.connect(dnsAddress, dnsPort, timeout: timeout);
      socket?.destroy();
      return true;
    } on SocketException {
      socket?.destroy();
    }
    return false;
  }

对_checkInternetAccess的调用最多需要一个超时时间才能完成(这里是3秒),如果我们可以到达任何一个DNS,它将在到达第一个DNS时立即完成,而不需要等待其他DNS(因为到达一个DNS就足以知道您有internet)。所有对_pingDns的调用都是并行完成的。

它似乎在IPV4网络上工作得很好,当我不能在IPV6网络上测试它时(我没有访问IPV6网络),我认为它仍然可以工作。它也适用于发布模式构建,但我还必须将我的应用提交给苹果,看看他们是否发现了这个解决方案的任何问题。

它也应该在大多数国家(包括中国)工作,如果它不能在一个工作,你可以添加一个DNS到列表中,可以从你的目标国家访问。

使用

dependencies:
  connectivity: ^0.4.2

我们从资源处得到的是

      import 'package:connectivity/connectivity.dart';

      Future<bool> check() async {
        var connectivityResult = await (Connectivity().checkConnectivity());
        if (connectivityResult == ConnectivityResult.mobile) {
          return true;
        } else if (connectivityResult == ConnectivityResult.wifi) {
          return true;
        }
        return false;
      }

未来对我来说没什么问题,我们必须每次都实现它,比如:

check().then((intenet) {
      if (intenet != null && intenet) {
        // Internet Present Case
      }
      // No-Internet Case
    });

所以为了解决这个问题,我创建了一个类,它接受一个布尔isNetworkPresent参数的函数,就像这样

methodName(bool isNetworkPresent){}

实用工具类是

import 'package:connectivity/connectivity.dart'; class NetworkCheck { Future<bool> check() async { var connectivityResult = await (Connectivity().checkConnectivity()); if (connectivityResult == ConnectivityResult.mobile) { return true; } else if (connectivityResult == ConnectivityResult.wifi) { return true; } return false; } dynamic checkInternet(Function func) { check().then((intenet) { if (intenet != null && intenet) { func(true); } else{ func(false); } }); } }

并使用连接检查实用程序

  fetchPrefrence(bool isNetworkPresent) {
    if(isNetworkPresent){

    }else{

    }
  }

我将使用这种语法

NetworkCheck networkCheck = new NetworkCheck();
networkCheck.checkInternet(fetchPrefrence)

我发现仅仅使用连接包不足以判断互联网是否可用。在安卓系统中,它只会检查是否有WIFI或移动数据是否打开,而不会检查是否有实际的互联网连接。在我的测试中,即使没有移动信号ConnectivityResult。Mobile将返回true。

在IOS系统中,我的测试发现,连接插件在手机没有信号的情况下能够正确地检测出是否有网络连接,而Android系统中才存在这个问题。

我找到的解决方案是使用data_connection_checker包以及连接性包。这只是通过向几个可靠的地址发出请求来确保有一个互联网连接,检查的默认超时时间大约是10秒。

我完成的isInternet函数看起来有点像这样:

  Future<bool> isInternet() async {
    var connectivityResult = await (Connectivity().checkConnectivity());
    if (connectivityResult == ConnectivityResult.mobile) {
      // I am connected to a mobile network, make sure there is actually a net connection.
      if (await DataConnectionChecker().hasConnection) {
        // Mobile data detected & internet connection confirmed.
        return true;
      } else {
        // Mobile data detected but no internet connection found.
        return false;
      }
    } else if (connectivityResult == ConnectivityResult.wifi) {
      // I am connected to a WIFI network, make sure there is actually a net connection.
      if (await DataConnectionChecker().hasConnection) {
        // Wifi detected & internet connection confirmed.
        return true;
      } else {
        // Wifi detected but no internet connection found.
        return false;
      }
    } else {
      // Neither mobile data or WIFI detected, not internet connection found.
      return false;
    }
  }

if (await DataConnectionChecker(). hasconnection)部分对于移动连接和wifi连接都是一样的,可能应该移动到一个单独的函数。我在这里没有这样做是为了让它更易于阅读。

我几乎读了所有的帖子,@dennmat的帖子对我最有用。虽然它对我没用,而且也过时了。我有更新颤振更新连接包(I。E connectivity_plus)和data_connection_checker(检查移动和wifi是否有实际的互联网连接)。 在这篇文章之后,你将能够连续监听互联网连接。

1. 添加依赖关系 A)连通性:^1.0.6 B) data_connection_checker: ^0.3.4

2. 处理所有连接的自定义类。

import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:data_connection_checker/data_connection_checker.dart'; 

class ConnectionUtil {
  //This creates the single instance by calling the `_internal` constructor specified below
  static final ConnectionUtil _singleton = new ConnectionUtil._internal();
  ConnectionUtil._internal();
  //This is what's used to retrieve the instance through the app
  static ConnectionUtil getInstance() => _singleton;
  //This tracks the current connection status
  bool hasConnection = false;
  //This is how we'll allow subscribing to connection changes
  StreamController connectionChangeController = StreamController();
  //flutter_connectivity
  final Connectivity _connectivity = Connectivity();
  void initialize() {
    _connectivity.onConnectivityChanged.listen(_connectionChange);
  }
  //flutter_connectivity's listener
  void _connectionChange(ConnectivityResult result) {
    hasInternetInternetConnection();
  }
  Stream get connectionChange => connectionChangeController.stream;
  Future<bool> hasInternetInternetConnection() async {
    bool previousConnection = hasConnection;
    var connectivityResult = await (Connectivity().checkConnectivity());
    //Check if device is just connect with mobile network or wifi
    if (connectivityResult == ConnectivityResult.mobile ||
        connectivityResult == ConnectivityResult.wifi) {
      //Check there is actual internet connection with a mobile network or wifi
      if (await DataConnectionChecker().hasConnection) {
        // Network data detected & internet connection confirmed.
        hasConnection = true;
      } else {
        // Network data detected but no internet connection found.
        hasConnection = false;
      }
    }
    // device has no mobile network and wifi connection at all
    else {
      hasConnection = false;
    }
    // The connection status changed send out an update to all listeners
    if (previousConnection != hasConnection) {
      connectionChangeController.add(hasConnection);
    }
    return hasConnection;
  }
}

检查任何地方的连接并倾听变化。

@override
  initState() {
    print('called');
    //Create instance
    ConnectionUtil connectionStatus = ConnectionUtil.getInstance();
    //Initialize
    connectionStatus.initialize();
    //Listen for connection change
    _connectionChangeStream = connectionStatus.connectionChange.listen((event) {
      print(event);
    });

    super.initState();
  }

切换飞行模式时检查日志。你应该得到有true和false值的日志。

注意:这将无法在flutter web工作,如果你想让它工作,请使用dio或http插件而不是data_connection_checker。

项目示例可以在这里找到。谢谢