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

这是我目前为止所做的:

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

上述方法行不通。


当前回答

我已经创建了一个包,(我认为)可以可靠地处理这个问题。

在pub.dev上的包

这个包在GitHub上

欢迎讨论。你可以使用GitHub上的问题跟踪器。


我不再认为这是一个可靠的方法:


想在@Oren的回答中添加一些东西:你真的应该再添加一个catch,它将捕获所有其他异常(为了安全起见),或者只是完全删除异常类型并使用一个catch,它处理所有异常:

案例1:

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;
} catch (_) {
  hasConnection = false;
}

或者更简单…

案例2:


try {
  await Firestore.instance
    .runTransaction((Transaction tx) {})
    .timeout(Duration(seconds: 5));
  hasConnection = true;
} catch (_) {
  hasConnection = false;
}

其他回答

我已经创建了一个包,(我认为)可以可靠地处理这个问题。

在pub.dev上的包

这个包在GitHub上

欢迎讨论。你可以使用GitHub上的问题跟踪器。


我不再认为这是一个可靠的方法:


想在@Oren的回答中添加一些东西:你真的应该再添加一个catch,它将捕获所有其他异常(为了安全起见),或者只是完全删除异常类型并使用一个catch,它处理所有异常:

案例1:

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;
} catch (_) {
  hasConnection = false;
}

或者更简单…

案例2:


try {
  await Firestore.instance
    .runTransaction((Transaction tx) {})
    .timeout(Duration(seconds: 5));
  hasConnection = true;
} catch (_) {
  hasConnection = false;
}

Null安全代码:

One time check: Create this method: Future<bool> hasNetwork() async { try { final result = await InternetAddress.lookup('example.com'); return result.isNotEmpty && result[0].rawAddress.isNotEmpty; } on SocketException catch (_) { return false; } } Usage: bool isOnline = await hasNetwork(); Setting up a listener: Add the following dependency to your pubspec.yaml file. connectivity_plus: ^2.0.2 Full code: void main() => runApp(MaterialApp(home: HomePage())); class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { Map _source = {ConnectivityResult.none: false}; final MyConnectivity _connectivity = MyConnectivity.instance; @override void initState() { super.initState(); _connectivity.initialise(); _connectivity.myStream.listen((source) { setState(() => _source = source); }); } @override Widget build(BuildContext context) { String string; switch (_source.keys.toList()[0]) { case ConnectivityResult.mobile: string = 'Mobile: Online'; break; case ConnectivityResult.wifi: string = 'WiFi: Online'; break; case ConnectivityResult.none: default: string = 'Offline'; } return Scaffold( body: Center(child: Text(string)), ); } @override void dispose() { _connectivity.disposeStream(); super.dispose(); } } class MyConnectivity { MyConnectivity._(); static final _instance = MyConnectivity._(); static MyConnectivity get instance => _instance; final _connectivity = Connectivity(); final _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'); isOnline = result.isNotEmpty && result[0].rawAddress.isNotEmpty; } on SocketException catch (_) { isOnline = false; } _controller.sink.add({result: isOnline}); } void disposeStream() => _controller.close(); }


截图:

来源:connectivity_plus和Günter Zöchbauer

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

只是试图简化代码使用连接包颤振。

import 'package:connectivity/connectivity.dart';

var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
  // I am connected to a mobile network.
} else if (connectivityResult == ConnectivityResult.wifi) {
  // I am connected to a wifi network.
} else {
  // I am not connected to the internet
}

对于登陆这里的其他人,我想添加到Günter Zöchbauer的答案,这是我实现一个实用程序的解决方案,以知道是否有互联网,而不管其他任何事情。

免责声明:

我对Dart和Flutter都是新手,所以这可能不是最好的方法,但很想得到反馈。


结合flutter_connectivity和Günter Zöchbauer的连接测试

我的需求

我不希望在需要检查连接的任何地方出现一堆重复的代码,我希望它在发生变化时自动更新组件或其他与连接相关的东西。

ConnectionStatusSingleton

首先我们设置一个Singleton。如果你不熟悉这种模式,网上有很多关于它们的好信息。但要点在于,您希望在应用程序生命周期中创建类的单个实例,并且能够在任何地方使用它。

这个单例连接到flutter_connectivity并监听连接性更改,然后测试网络连接,然后使用StreamController更新任何关心的内容。

它是这样的:

import 'dart:io'; //InternetAddress utility
import 'dart:async'; //For StreamController/Stream

import 'package:connectivity/connectivity.dart';

class ConnectionStatusSingleton {
    //This creates the single instance by calling the `_internal` constructor specified below
    static final ConnectionStatusSingleton _singleton = new ConnectionStatusSingleton._internal();
    ConnectionStatusSingleton._internal();

    //This is what's used to retrieve the instance through the app
    static ConnectionStatusSingleton getInstance() => _singleton;

    //This tracks the current connection status
    bool hasConnection = false;

    //This is how we'll allow subscribing to connection changes
    StreamController connectionChangeController = new StreamController.broadcast();

    //flutter_connectivity
    final Connectivity _connectivity = Connectivity();

    //Hook into flutter_connectivity's Stream to listen for changes
    //And check the connection status out of the gate
    void initialize() {
        _connectivity.onConnectivityChanged.listen(_connectionChange);
        checkConnection();
    }

    Stream get connectionChange => connectionChangeController.stream;

    //A clean up method to close our StreamController
    //   Because this is meant to exist through the entire application life cycle this isn't
    //   really an issue
    void dispose() {
        connectionChangeController.close();
    }

    //flutter_connectivity's listener
    void _connectionChange(ConnectivityResult result) {
        checkConnection();
    }

    //The test to actually see if there is a connection
    Future<bool> checkConnection() async {
        bool previousConnection = hasConnection;

        try {
            final result = await InternetAddress.lookup('google.com');
            if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
                hasConnection = true;
            } else {
                hasConnection = false;
            }
        } on SocketException catch(_) {
            hasConnection = false;
        }

        //The connection status changed send out an update to all listeners
        if (previousConnection != hasConnection) {
            connectionChangeController.add(hasConnection);
        }

        return hasConnection;
    }
}

使用

初始化

首先,我们必须确保调用了我们单例的initialize。但只有一次。 这部分取决于你,但我在我的应用程序的main():

void main() {
    ConnectionStatusSingleton connectionStatus = ConnectionStatusSingleton.getInstance();
    connectionStatus.initialize();

    runApp(MyApp());

    //Call this if initialization is occuring in a scope that will end during app lifecycle
    //connectionStatus.dispose();   
}

在Widget或其他地方

import 'dart:async'; //For StreamSubscription

...

class MyWidgetState extends State<MyWidget> {
    StreamSubscription _connectionChangeStream;

    bool isOffline = false;

    @override
    initState() {
        super.initState();

        ConnectionStatusSingleton connectionStatus = ConnectionStatusSingleton.getInstance();
        _connectionChangeStream = connectionStatus.connectionChange.listen(connectionChanged);
    }

    void connectionChanged(dynamic hasConnection) {
        setState(() {
            isOffline = !hasConnection;
        });
    }

    @override
    Widget build(BuildContext ctxt) {
        ...
    }
}

希望其他人觉得这有用!


示例github repo: https://github.com/dennmat/flutter-connectiontest-example

在模拟器中切换飞行模式以查看结果