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

这是我目前为止所做的:

  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();
}

其他回答

连接插件在其文档中声明,它只在有网络连接的情况下提供信息,但不包括网络连接到Internet的情况。使用下面的代码,不要忘记使用“.timeout()”,因为使用“await”可能会永远卡住。

import 'dart:io';

Future<bool> isConnected() async {
  try {
    List<InternetAddress> result = await InternetAddress.lookup('example.com')
        .timeout(Duration(seconds: 5));

    //
    if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
      return true;
    }
    //
    else {
      return false;
    }
  } on SocketException catch (_) {
    return false;
  }
}

在@dennmatt的回答之后,我注意到InternetAddress。查找可能会返回成功的结果,即使互联网连接断开-我测试它从我的模拟器连接到我的家庭WiFi,然后断开我的路由器的电缆。我认为原因是路由器缓存了域查找结果,所以它不必在每个查找请求时查询DNS服务器。

不管怎样,如果你像我一样使用Firestore,你可以用一个空事务替换try-SocketException-catch块并捕获TimeoutExceptions:

try {
  await Firestore.instance.runTransaction((Transaction tx) {}).timeout(Duration(seconds: 5));
  hasConnection = true;
} on PlatformException catch(_) { // May be thrown on Airplane mode
  hasConnection = false;
} on TimeoutException catch(_) {
  hasConnection = false;
}

另外,请注意,previousConnection是在async internet -check之前设置的,因此理论上,如果checkConnection()在短时间内被调用多次,那么在一行中可能有多个hasConnection=true或多个hasConnection=false。 我不确定@dennmatt是否故意这样做,但在我们的用例中没有副作用(setState只被调用两次,具有相同的值)。

我为小部件状态创建了一个基类

使用BaseState<LoginPage>代替State<LoginPage> 然后使用布尔变量isOnline

Text(isOnline ? 'is Online' : 'is Offline')

首先,添加连接性插件:

dependencies:
  connectivity: ^0.4.3+2

然后添加BaseState类

import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';

import 'package:connectivity/connectivity.dart';
import 'package:flutter/widgets.dart';

/// a base class for any statful widget for checking internet connectivity
abstract class BaseState<T extends StatefulWidget> extends State {

  void castStatefulWidget();

  final Connectivity _connectivity = Connectivity();

  StreamSubscription<ConnectivityResult> _connectivitySubscription;

  /// the internet connectivity status
  bool isOnline = true;

  /// initialize connectivity checking
  /// Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initConnectivity() async {
    // Platform messages may fail, so we use a try/catch PlatformException.
    try {
      await _connectivity.checkConnectivity();
    } on PlatformException catch (e) {
      print(e.toString());
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) {
      return;
    }

    await _updateConnectionStatus().then((bool isConnected) => setState(() {
          isOnline = isConnected;
        }));
  }

  @override
  void initState() {
    super.initState();
    initConnectivity();
    _connectivitySubscription = Connectivity()
        .onConnectivityChanged
        .listen((ConnectivityResult result) async {
      await _updateConnectionStatus().then((bool isConnected) => setState(() {
            isOnline = isConnected;
          }));
    });
  }

  @override
  void dispose() {
    _connectivitySubscription.cancel();
    super.dispose();
  }

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

您需要像这样在您的状态下强制转换小部件

@override
  void castStatefulWidget() {
    // ignore: unnecessary_statements
    widget is StudentBoardingPage;
  }

基于这个答案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;
    });
  }

我有一些问题与接受的答案,但似乎它解决了别人的答案。我想要一个解决方案,可以从它使用的url得到响应,所以我认为http将是伟大的功能,为此,我发现这个答案真的很有帮助。如何使用HTTP请求(Flutter/Dart)检查Internet连接?