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

这是我目前为止所做的:

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

上述方法行不通。


当前回答

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:app_settings/app_settings.dart';
import 'package:connectivity/connectivity.dart';

class InternetConnect extends StatefulWidget {
  @override
  InternetConnectState createState() => InternetConnectState();
}

class InternetConnectState extends State<InternetConnect> {
  ConnectivityResult previous;
  bool dialogshown = false;
  StreamSubscription connectivitySubscription;

  Future<bool> checkinternet() async {
    try {
      final result = await InternetAddress.lookup('google.com');
      if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
        return Future.value(true);
      }
    } on SocketException catch (_) {
      return Future.value(false);
    }
  }

  void checkInternetConnect(BuildContext context) {
    connectivitySubscription = Connectivity()
        .onConnectivityChanged
        .listen((ConnectivityResult connresult) {
      if (connresult == ConnectivityResult.none) {
        dialogshown = true;
        showDialog(
            context: context, barrierDismissible: false, child: alertDialog());
      } else if (previous == ConnectivityResult.none) {
        checkinternet().then((result) {
          if (result == true) {
            if (dialogshown == true) {
              dialogshown = false;
              Navigator.pop(context);
            }
          }
        });
      }

      previous = connresult;
    });
  }

  AlertDialog alertDialog() {
    return AlertDialog(
      title: Text('ERROR'),
      content: Text("No Internet Detected."),
      actions: <Widget>[
        FlatButton(
          // method to exit application programitacally

          onPressed: () {
            AppSettings.openWIFISettings();
          },
          child: Text("Settings"),
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

    and you can use this method in init of any class

@override
void initState() {
  // TODO: implement initState
  InternetConnectState().checkInternetConnect(context);
  super.initState();
}

其他回答

我发现仅仅使用连接包不足以判断互联网是否可用。在安卓系统中,它只会检查是否有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连接都是一样的,可能应该移动到一个单独的函数。我在这里没有这样做是为了让它更易于阅读。

使用observe_internet_connectivity包。

可用的特性

检查设备是否有互联网连接

  final hasInternet = await InternetConnectivity().hasInternetConnection;
  if (hasInternet) {
    //You are connected to the internet
  } else {
    //"No internet connection
  }

通过流收听互联网连接变化

  final subscription =
      InternetConnectivity().observeInternetConnection.listen((bool hasInternetAccess) {
        if(!hasInternetAccess){
          showToast('No Internet Connection');
        }
      });

   await Future.delayed(const Duration(seconds: 10 ));
   subscription.cancel();

使用InternetConnectivityListener监听flutter小部件内的互联网连接变化

    return InternetConnectivityListener(
      connectivityListener: (BuildContext context, bool hasInternetAccess) {
        if (hasInternetAccess) {
          context.showBanner('You are back Online!', color: Colors.green);
        } else {
          context.showBanner('No internet connection', color: Colors.red);
        }
      },
      child: Scaffold(
        body: Container(),
      ),
    );

使用InternetConnectivityBuilder构建互联网连接感知小部件

    return InternetConnectivityBuilder(
      connectivityBuilder: (BuildContext context, bool hasInternetAccess, Widget? child) { 
        if(hasInternetAccess) {
          return OnlineWidget();
        } else {
          return OfflineWidget();
        }
      },
      child: ChildWidget(),
    );

对我来说,我只是在Firebase中创建一个数据,并使用未来构建器来等待数据。在这里,就像这样,你可以检查连接是否太慢,所以数据将被加载:

FutureBuilder(
    future: _getImage(context),
    builder: (context, snapshot) {
      switch (snapshot.connectionState) {
        case ConnectionState.none:
          return Text('Press button to start.');
        case ConnectionState.active:
        case ConnectionState.waiting:
          return Container(
              height:
                  MediaQuery.of(context).size.height / 1.25,
              width:
                  MediaQuery.of(context).size.width / 1.25,
              child: Loading());
        case ConnectionState.done:
          if (snapshot.hasData) {
            return snapshot.data;
          } else {
            return FlatButton(
              onPressed: () {
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (context) =>
                            ProfilePage()));
              },
              child: Icon(
                Icons.add_a_photo,
                size: 50,
              ),
            );
          }
        // You can reach your snapshot.data['url'] in here
      }
      return null;
    },
  ),

连接插件在其文档中声明,它只在有网络连接的情况下提供信息,但不包括网络连接到Internet的情况

请注意,在Android上,这并不保证连接到互联网。例如,应用程序可能有wifi接入,但它可能是一个VPN或酒店wifi,没有接入。

你可以使用

import 'dart:io';
...
try {
  final result = await InternetAddress.lookup('example.com');
  if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
    print('connected');
  }
} on SocketException catch (_) {
  print('not connected');
}

更新

不建议使用连接包。请使用官方的Flutter Community connectivity_plus包。

基于这个答案https://stackoverflow.com/a/68436867/10761151

如果你使用dart零安全,你会得到一个错误, 因此,您可以将依赖项data_connection_checker: ^0.3.4更新为internet_connection_checker: ^0.0.1+2

你可以用这个代码

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

class ConnectionUtil {
  static final ConnectionUtil _singleton = new ConnectionUtil._internal();
  ConnectionUtil._internal();

  static ConnectionUtil getInstance() => _singleton;

  bool hasConnection = false;

  StreamController connectionChangeController = StreamController();

  final Connectivity _connectivity = Connectivity();
  void initialize() {
    _connectivity.onConnectivityChanged.listen(_connectionChange);
  }

  void _connectionChange(ConnectivityResult result) {
    _hasInternetInternetConnection();
  }

  Stream get connectionChange => connectionChangeController.stream;
  Future<bool> _hasInternetInternetConnection() async {
    bool previousConnection = hasConnection;
    var connectivityResult = await (Connectivity().checkConnectivity());
    if (connectivityResult == ConnectivityResult.mobile || connectivityResult == ConnectivityResult.wifi) {
      // this is the different
      if (await InternetConnectionChecker().hasConnection) {
        hasConnection = true;
      } else {
        hasConnection = false;
      }
    } else {
      hasConnection = false;
    }

    if (previousConnection != hasConnection) {
      connectionChangeController.add(hasConnection);
    }
    return hasConnection;
  }
}

在有状态小部件上可以实现此代码

  bool hasInterNetConnection = false;

  @override
  initState() {
    ConnectionUtil connectionStatus = ConnectionUtil.getInstance();
    connectionStatus.initialize();
    connectionStatus.connectionChange.listen(connectionChanged);

    super.initState();
  }

  void connectionChanged(dynamic hasConnection) {
    setState(() {
      hasInterNetConnection = hasConnection;
    });
  }