243

I have a network call to be executed. But before doing that I need to check whether the device have internet connectivity.

This is what i have done so far:

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

Above method is not working.

Rissmon Suresh
  • 13,173
  • 5
  • 29
  • 38

28 Answers28

390

The connectivity plugin states in its docs that it only provides information if there is a network connection, but not if the network is connected to the Internet

Note that on Android, this does not guarantee connection to Internet. For instance, the app might have wifi access but it might be a VPN or a hotel WiFi with no access.

You can use

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

Update

The connectivity package is deprecated. Use the official Flutter Community connectivity_plus package instead.

genericUser
  • 4,417
  • 1
  • 28
  • 73
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 3
    I am getting error "isNotEmpty is not declared inside InternetAddress" – Rissmon Suresh Apr 04 '18 at 12:01
  • Ups, I deleted the code locally already, but I think it should be `result[0].rawAddress.isNotEmpty`. Sorry for that. – Günter Zöchbauer Apr 04 '18 at 12:04
  • I'm getting errors on this code as well on ` on SocketException catch(_) ` . Says `on ` is undefined. – ThinkDigital May 28 '18 at 19:39
  • Please fix the curly brackets: you have 3 `{` and 2 `}`. – Cœur Jun 27 '18 at 04:02
  • 2
    Can this be achieved in background? Like I have a queue of tasks pending for execution and waiting for internet but the app is closed? – Pushan Gupta Oct 06 '18 at 16:23
  • https://pub.dartlang.org/packages/android_alarm_manager allows to execute code in the background (at least on Android, it's a bit more difficult on iOS). I don't know if it allows to access plugins though. – Günter Zöchbauer Oct 07 '18 at 12:26
  • 124
    Please note that google.com is not accessible inside in China and as such the example will hang if used in China. In order to expand your audience please avoid using google.com and use example.com instead. final result = await InternetAddress.lookup('example.com'); – otboss Feb 28 '19 at 21:55
  • 18
    This does not work for me `if (result.isNotEmpty && result[0].rawAddress.isNotEmpty)` returns true when there's wifi but not internet connection. – Denn Apr 26 '19 at 07:29
  • @Denn Which url did you use? – CopsOnRoad May 08 '19 at 12:00
  • 1
    @CopsOnRoad I used `google.com` and also tried my own api url. does it matter which one I use? – Denn May 15 '19 at 05:27
  • @Denn Even I didn't used to think if url matters, but someone said `google.com` doesn't work in China so I asked you. – CopsOnRoad May 15 '19 at 06:29
  • var result = await Connectivity().checkConnectivity(); giving me error like "ConnectivityService: Neither user 11177 nor current process has android.permission.ACCESS_NETWORK_STATE., null)" Can anybody help ? – Jay Mungara Sep 18 '19 at 05:32
  • https://developer.android.com/training/basics/network-ops/managing might help. The manifest example shows how to add the permission. Search the page for .ACCESS_NETWORK_STATE – Günter Zöchbauer Sep 18 '19 at 05:38
  • @LOG_TAG can you please elaborate? – Günter Zöchbauer Oct 11 '19 at 07:51
  • 1
    @GünterZöchbauer sorry, without using connectivity: ^0.4.3+2 via firebase flutter sdk https://firebase.google.com/docs/database/android/offline-capabilities via dart version of database.getReference(".info/connected"); is possible? – LOG_TAG Oct 11 '19 at 08:52
  • Is it possible to create an app similar to Internet Speed Meter using Flutter? – Sanal S Oct 14 '19 at 07:13
  • There isn't really a limitation on what you can do with Flutter except perhaps things like pure background apps and launcher plugins. You might need to call out to native APIs for certain things though. – Günter Zöchbauer Oct 14 '19 at 07:19
  • 2
    hey guys,it's working when we have connected it with wifi..but wifi has no internet it's still showing connected...any solution for this issue? – Zeeshan Ansari Nov 05 '19 at 10:20
  • 1
    @GünterZöchbauer can I configure the timeout time? In my tests your code takes about 2.5 minutes to report that the user is disconnected. – Michel Feinstein Jan 20 '20 at 04:24
  • 1
    @mFeinstein if yo do not use `await` you get a `Future` where you can set a timeout https://stackoverflow.com/questions/33897140/how-to-timeout-a-future-computation-after-a-timelimit – Günter Zöchbauer Jan 20 '20 at 04:43
  • 10
    Oh, yes, I completely forgot about this! Actually I think I can keep using `await`, I can just append `.timeout` after `lookup()`. – Michel Feinstein Jan 21 '20 at 04:48
  • Is there any way to detect network state change without using connectivity plugin? – Sagar V Apr 03 '20 at 10:58
  • @SagarV is there a specific reason you don't want to use the plugin? – Günter Zöchbauer Apr 03 '20 at 12:12
  • This code works for me but some users in my production app complaint that they are "not connected" if they use WIFI (while they are "connect" if they if they use cellular data). What could it be the culprit? – M4trix Dev Mar 06 '21 at 09:34
  • For some reason, the code works in the emulator but not in a real device. Has anybody ever experienced that ? – user54517 Mar 30 '21 at 10:16
  • 2
    @BarnettTemwaMsiska "does not work" is something you should generally avoid when asking for support. It could be that your computer has no power to the CIA hacked your computer and installed spyware. If you need guidance, provide proper information about what you tried and how the result is different from what you expected. Perhaps better to create a new question with the information required to reproduce. – Günter Zöchbauer Apr 29 '21 at 07:03
  • Since I have users in China, I realized that google.com is banned in China. So I advise you to use another site to check if the user has an internet connection. Personally I use 'example.com' – bulgarian-beast May 03 '21 at 11:58
  • I cannot catch SocketException – vannak May 27 '21 at 04:15
  • just curious, example.com uses insecure http connection. wouldn't this be a problem in production when you disable insecure connections? – Norbert Jun 06 '21 at 21:42
  • 2
    I doesn't connect, it just tries to resolve the hostname. It assumes that it has a connection to the internet if it gets an IP. – Günter Zöchbauer Jun 07 '21 at 08:13
  • 4
    This does not solve the issue in Flutter 2. As mentioned by Günter Zöchbauer the 1st time im offline its not able to resolve the hostname. But the 2nd time i guess it caches it and returns the address when u go offline – Harshvardhan R Sep 03 '21 at 09:25
  • 1
    it wont work on Flutter Web as uses dart.io lib. data_connection_checker does not support null safety. internet_connection_checker wont work on Flutter Web as well. What can we do? – Bruno Minuk Jan 07 '22 at 13:46
  • https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine – Günter Zöchbauer Jan 09 '22 at 15:55
  • this always returns true for me – sleepwalk Apr 11 '23 at 04:57
  • 1
    InternetAddress.lookup returns cached result after the first request to lookup example.com, even if you go offline. There is an issue describing this behaviour - https://github.com/dart-lang/sdk/issues/52156 – Petru Lutenco Jun 12 '23 at 13:18
  • 1
    I tried this and is unreliable, I think the problem is with connectivity_plus package. Replaced the implementation with https://pub.dev/packages/internet_connection_checker and it worked like a charm. – vijay Aug 22 '23 at 15:14
130

For anyone else who lands here I'd like to add on to Günter Zöchbauer's answer this was my solution for implementing a utility to know if there's internet or not regardless of anything else.

Disclaimer:

I'm new to both Dart and Flutter so this may not be the best approach, but would love to get feedback.


Combining flutter_connectivity and Günter Zöchbauer's connection test

My requirements

I didn't want to have a bunch of repeated code anywhere I needed to check the connection and I wanted it to automatically update components or anything else that cared about the connection whenever there was a change.

ConnectionStatusSingleton

First we setup a Singleton. If you're unfamiliar with this pattern there's a lot of good info online about them. But the gist is that you want to make a single instance of a class during the application life cycle and be able to use it anywhere.

This singleton hooks into flutter_connectivity and listens for connectivity changes, then tests the network connection, then uses a StreamController to update anything that cares.

It looks like this:

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

Usage

Initialization

First we have to make sure we call the initialize of our singleton. But only once. This parts up to you but I did it in my app's 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();   
}

In Widget or elsewhere

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) {
        ...
    }
}

Hope somebody else finds this useful!


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

Toggle airplane mode in the emulator to see the result

dennmat
  • 2,618
  • 2
  • 17
  • 20
  • I put the first code in Main.dart and tried with a HomePage,but this trhows the following error Could not load source 'dart:async/broadcast_stream_controller.dart': . – Rajesh Dec 20 '18 at 16:35
  • There's likely another error and that's just the editor trying to open the file but it doesn't have access to it. I modified this example from my code to generalize it. May have broke something. I'll check when I'm back home. But if you look at the debug panel can you find the real error? – dennmat Dec 20 '18 at 17:13
  • 3
    Tested the code and it's working for me I'd need more info to help out. – dennmat Dec 21 '18 at 00:40
  • i tried now too,but it throws the same error,Could u please make a sample flutter app in github?? – Rajesh Dec 21 '18 at 04:24
  • 4
    Ahh, ok I see it. So again for your future reference the error you're posting is just the editor trying to open the file where it think the error occured. The real error should be available in your editors debug console/stack trace panel. So I guess runApp returns I assumed it would run for the entirety of the programs life. Seeing as this is in the main the dispose isn't really necessary here so just remove `connectionStatus.dispose()` assuming you're setting it up in the `main()` like above. Will update post and link to github example. – dennmat Dec 21 '18 at 04:46
  • now the error is gone,But the bugs are,when i swtich from one wifi to another Wifi it detects Actvie Internet Connection,but Stayign on the same Wifi,i turned of Internet,..it doesn't detect the changes,.. – Rajesh Dec 21 '18 at 13:20
  • 1
    To just detect if wifi or cellular is being switched you only need flutter connectivity. This wrapper checks the connection after the switch occurs. But won't alert every network change. If you're using the emulator toggling airplane mode is the easiest way to lose internet connection. If you're on an actual device you'd have to make sure you weren't still connected to a mobile network with data. – dennmat Dec 21 '18 at 14:47
  • my clear requirement is detecting LIVE ACTIVE INTERNET CONNECTION changes,like youtube and google go apps,but no solutions found for that,t tried streamiing http results,none of them helped – Rajesh Dec 23 '18 at 13:12
  • 1
    There's a few options for that, you can modify the above to use Timer to test frequently. Or just test frequently using the Timer utility. See: https://api.dartlang.org/stable/2.1.0/dart-async/Timer-class.html Another option is testing the connection before every request you send. Although seems like you may be looking for something like websockets. Anyway good luck – dennmat Dec 29 '18 at 03:09
  • @dennmat widget displays as connected. when I open application while connection is off. Can you check that? – Kavin-K Dec 30 '18 at 11:17
  • Aw it's likely due to the first check occurring before the component even exists and in my example it defaults to thinking it's online. Instead you could assign the default value of `isOffline` to `!mySingletonInstance.hasConnection`. – dennmat Jan 06 '19 at 16:34
  • Is it really necessary to save _connectionChangeStream in the state? My linter shows a warning of: "The value of the field '_connectionChangeStream' isn't used." – Oren Feb 21 '19 at 20:11
  • 4
    Shouldn't we cancel the subscription in the widget's dispose() function? I see this is done in other StreamController examples like here: https://stackoverflow.com/questions/44788256/updating-data-in-flutter – Oren Feb 21 '19 at 20:21
  • I tried you GitHub repo. But it has a bug. first time application loading without connecting internet, showing "connected". How to fix this issue? – BIS Tech Mar 11 '19 at 07:38
  • Nice implementation! Thanks to Dart's support for top-level variables, your singleton can be a lot simpler, though: `final connectionStatus = new ConnectionStatusSingleton.init();` – Jannie Theunissen Apr 25 '19 at 15:05
  • For WEB support, I replaced `dart.io` with [`dio`](https://pub.dev/packages/dio) – Stack Underflow Jul 07 '20 at 21:56
  • hi, you are listening to connectivity changes and then checking the internet connectivity. but connection to internet might be lost while there is connectivity to existing source wifi or mobile. – RL Shyam Aug 20 '20 at 06:19
  • I think we must cancel this line `_connectivity.onConnectivityChanged.listen(_connectionChange);` on `dispose`. Put this line in variable to call `.cancel()` later in `dispose` function. – Taufik Nur Rahmanda Mar 11 '21 at 04:37
  • make sure you put WidgetsFlutterBinding.ensureInitialized(); as first line on main() – skyllet Apr 25 '21 at 10:51
  • I tried the solution above but I keep getting an error as follows: `[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Null check operator used on a null value` Which points to the error on listed `_connectivity.onConnectivityChanged.listen(_connectionChange);` – Aashwiin Roghan Jul 15 '21 at 06:37
  • @AashwiinRoghan Yea I had the same issue, this post seems old. I have updated with same logic. check below – Kunchok Tashi Jul 19 '21 at 07:49
  • the best solution – yovie Feb 09 '22 at 00:48
122

Null Safe code:

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

Screenshot:

enter image description here

Credit to : connectivity_plus and Günter Zöchbauer

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
44

I found that just using the connectivity package was not enough to tell if the internet was available or not. In Android it only checks if there is WIFI or if mobile data is turned on, it does not check for an actual internet connection . During my testing, even with no mobile signal ConnectivityResult.mobile would return true.

With IOS my testing found that the connectivity plugin does correctly detect if there is an internet connection when the phone has no signal, the issue was only with Android.

The solution I found was to use the data_connection_checker package along with the connectivity package. This just makes sure there is an internet connection by making requests to a few reliable addresses, the default timeout for the check is around 10 seconds.

My finished isInternet function looked a bit like this:

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

The if (await DataConnectionChecker().hasConnection) part is the same for both mobile and wifi connections and should probably be moved to a separate function. I've not done that here to leave it more readable.

starball
  • 20,030
  • 7
  • 43
  • 238
abernee
  • 449
  • 4
  • 6
  • 3
    Welcome to stackoverflow. Just wondering, what is the advantage over just using `await DataConnectionChecker().hasConnection` in the first place? – Herbert Poul Apr 30 '20 at 08:27
  • 4
    The only reason is that on IOS the connectivity package can tell pretty much instantly that there is no connection. If I just used the data_connection_checker package the app on IOS would have to wait until the http request it made timed out, around 10 seconds, before returning false. This may be acceptable in some cases though. The connectivity package can also tell if you are using WIFI or mobile data which I don't need to know here but may be useful to know. – abernee Apr 30 '20 at 11:51
  • Thanks TDM, I've edited the answer with your modifications. – abernee Jul 02 '20 at 10:03
  • 1
    DataConnectionChecker is deprecated. Use internet_connection_checker https://pub.dev/packages/internet_connection_checker – seunggi Nov 22 '21 at 05:17
24

Using

dependencies:
  connectivity: ^0.4.2

what we got from resouces is

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

Future is little problematic for me, we have to implement it every single time like :

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

So to solve this problem i have created a class Which accept a function with boolean isNetworkPresent parameter like this

methodName(bool isNetworkPresent){}

And the Utility Class is

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

And to use connectivity-check utilty

  fetchPrefrence(bool isNetworkPresent) {
    if(isNetworkPresent){

    }else{

    }
  }

i will use this syntax

NetworkCheck networkCheck = new NetworkCheck();
networkCheck.checkInternet(fetchPrefrence)
Tushar Pandey
  • 4,557
  • 4
  • 33
  • 50
7

I've created a package that (I think) deals reliably with this issue.

The package on pub.dev

The package on GitHub

Discussion is very welcome. You can use the issues tracker on GitHub.


I no longer think this below is a reliable method:


Wanna add something to @Oren's answer: you should really add one more catch, which will catch all other exceptions (just to be safe), OR just remove the exception type altogether and use a catch, that deals with all of the exceptions:

Case 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;
}

or even simpler...

Case 2:


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

I made a base class for widget state

Usage instead of State<LoginPage> use BaseState<LoginPage> then just use the boolean variable isOnline

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

First, add connectivity plugin:

dependencies:
  connectivity: ^0.4.3+2

Then add the BaseState class

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

And you need to cast the widget in your state like this

@override
  void castStatefulWidget() {
    // ignore: unnecessary_statements
    widget is StudentBoardingPage;
  }
amorenew
  • 10,760
  • 10
  • 47
  • 69
  • 3
    how can i use this class? – DolDurma Aug 26 '19 at 07:30
  • @DolDurma Just add it and import it then instead of State use BaseState then just use the boolean variable isOnline – amorenew Aug 26 '19 at 08:23
  • with this code i can't get valiables from `widget`. for example: `RegisterBloc get _registerBloc => widget.registerBloc;` i get this error `error: The getter 'registerBloc' isn't defined for the class 'StatefulWidget'. (undefined_getter at lib\screens\fragmemt_register\view\register_mobile_number.dart:29)` see this implemetation: `class _FragmentRegisterMobileNumberState extends BaseState with SingleTickerProviderStateMixin { RegisterBloc get _registerBloc => widget.registerBloc;` – DolDurma Aug 26 '19 at 09:07
  • @DolDurma I am not sure what is the issue without a GitHub sample because this information is not enough – amorenew Aug 26 '19 at 09:15
  • 1
    please check this repo and show me how can i use `is_online` to log in console https://github.com/MahdiPishguy/flutter-connectivity-sample – DolDurma Aug 28 '19 at 15:59
  • @DolDurma just use AppBar( title: Text(isOnline?'Online':'Offline'), ) – amorenew Aug 29 '19 at 07:52
  • how can i resolve this error? `E/flutter ( 2969): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback. E/flutter ( 2969): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree` – DolDurma Sep 05 '19 at 09:36
  • use if(mount) in your set state – amorenew Sep 06 '19 at 12:59
  • i tested that before posting comment, not any change :( – DolDurma Sep 07 '19 at 17:41
  • @DolDurma just use (widget as MyHomePage).title – amorenew Sep 08 '19 at 12:22
7

Well I read almost all post and @dennmat post is most usedful to me. though it did't work for me and it is outdated too. I have update with flutter updated connectivity package(i.e connectivity_plus) and data_connection_checker(to check whether there is actual internet connection for mobile and wifi).
After this post you will be able to listen for internet connection continuosly.

1. Add dependencies
a) connectivity_plus: ^1.0.6
b) data_connection_checker: ^0.3.4

2. Custom class that handle all the connection.

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;
  }
}
  1. Check for connection in anywhere and listen for change.
@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();
  }

Now check the log while toggle flight mode. you should get log with true and false value.

Note: this will not work in flutter web, if you wish to make it work than use dio or http plugin instead of data_connection_checker.

Example Project can be found here. Thanks

Kunchok Tashi
  • 2,413
  • 1
  • 22
  • 30
5

I had an issue with the proposed solutions, using lookup does not always return the expected value.

This is due to DNS caching, the value of the call is cached and intead of doing a proper call on the next try it gives back the cached value. Of course this is an issue here as it means if you lose connectivity and call lookup it could still return the cached value as if you had internet, and conversely, if you reconnect your internet after lookup returned null it will still return null for the duration of the cache, which can be a few minutes, even if you do have internet now.

TL;DR: lookup returning something does not necessarily mean you have internet, and it not returning anything does not necessarily mean you don't have internet. It is not reliable.

I implemented the following solution by taking inspiration from the data_connection_checker plugin:

 /// 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;
  }

The call to _checkInternetAccess takes at most a duration of timeout to complete (3 seconds here), and if we can reach any of the DNS it will complete as soon as the first one is reached, without waiting for the others (as reaching one is enough to know you have internet). All the calls to _pingDns are done in parallel.

It seems to work well on an IPV4 network, and when I can't test it on an IPV6 network (I don't have access to one) I think it should still work. It also works on release mode builds, but I yet have to submit my app to Apple to see if they find any issue with this solution.

It should also work in most countries (including China), if it does not work in one you can add a DNS to the list that is accessible from your target country.

Quentin
  • 758
  • 9
  • 11
  • I think this will suffice more than enough ```dart Future isConnectedToInternet() async { try { (await Socket.connect( InternetAddress('8.8.8.8', type: InternetAddressType.IPv4), 53, timeout: const Duration(seconds: 3), )) .destroy(); } on SocketException { return false; } return true; } ``` – Mehmet Filiz Aug 29 '23 at 12:50
4

Following @dennmatt 's answer, I noticed that InternetAddress.lookup may return successful results even if the internet connection is off - I tested it by connecting from my simulator to my home WiFi, and then disconnecting my router's cable. I think the reason is that the router caches the domain-lookup results so it does not have to query the DNS servers on each lookup request.

Anyways, if you use Firestore like me, you can replace the try-SocketException-catch block with an empty transaction and 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;
}

Also, please notice that previousConnection is set before the async intenet-check, so theoretically if checkConnection() is called multiple times in a short time, there could be multiple hasConnection=true in a row or multiple hasConnection=false in a row. I'm not sure if @dennmatt did it on purpose or not, but in our use-case there were no side effects (setState was only called twice with the same value).

Oren
  • 2,767
  • 3
  • 25
  • 37
3

The connectivity: package does not guarantee the actual internet connection (could be just wifi connection without internet access).

Quote from the documentation:

Note that on Android, this does not guarantee connection to Internet. For instance, the app might have wifi access but it might be a VPN or a hotel WiFi with no access.

If you really need to check the connection to the www Internet the better choice would be

data_connection_checker package

Andrew
  • 36,676
  • 11
  • 141
  • 113
  • AGREED. That is why combining the __**Connectivity**__ and __**Data Connection Checker**__ packages (as explained here -> https://stackoverflow.com/a/62063600/3002719) is a better solution to this problem. – SilSur Jun 04 '21 at 07:15
3

use connectivity_widget: ^0.1.7

add dependencies:

dependencies:
     connectivity_widget: ^0.1.7

add code:

           ConnectivityWidget(
            builder: (context, isOnline) => Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    "${isOnline ? 'Connected' : 'Offline'}",
                    style: TextStyle(
                        fontSize: 30,
                        color: isOnline ? Colors.green : Colors.red),
                  ),
                ],
              ),
            ),
          )

OUTPUT:

enter image description here

Sandeep Pareek
  • 1,636
  • 19
  • 21
2

Here Is My Solution It Checks Internet Connectivity as well as Data Connection I hope You Like it.

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"),
        ),
      ),
    );
  }
}
Tirth Raj
  • 31
  • 2
2

I ultimately (though reluctantly) settled on the solution given by @abernee in a previous answer to this question. I always try and use as few external packages in my projects as possible - as I know external packages are the only [ potential ] points of failure in the software I create. So to link to TWO external packages just for a simple implementation like this was not easy for me.

Nevertheless, I took abernee's code and modified it to make it leaner and more sensible. By sensible I mean he consumes the power of the Connectivity package in his function but then wastes it internally by not returning the most valuable outputs from this package ( i.e. the network identification ). So here is the modified version of abernee's solution:

import 'package:connectivity/connectivity.dart';
import 'package:data_connection_checker/data_connection_checker.dart';


// 'McGyver' - the ultimate cool guy (the best helper class any app can ask for).
class McGyver {

  static Future<Map<String, dynamic>> checkInternetAccess() async {
    //* ////////////////////////////////////////////////////////////////////////////////////////// *//
    //*   INFO: ONLY TWO return TYPES for Map 'dynamic' value => <bool> and <ConnectivityResult>   *//
    //* ////////////////////////////////////////////////////////////////////////////////////////// *//
    Map<String, dynamic> mapCon;
    final String isConn = 'isConnected', netType = 'networkType';
    ConnectivityResult conRes = await (Connectivity().checkConnectivity());
    switch (conRes) {
      case ConnectivityResult.wifi:   //* WiFi Network: true !!
        if (await DataConnectionChecker().hasConnection) {   //* Internet Access: true !!
          mapCon = Map.unmodifiable({isConn: true, netType: ConnectivityResult.wifi});
        } else {
          mapCon = Map.unmodifiable({isConn: false, netType: ConnectivityResult.wifi});
        }
        break;
      case ConnectivityResult.mobile:   //* Mobile Network: true !!
        if (await DataConnectionChecker().hasConnection) {   //* Internet Access: true !!
          mapCon = Map.unmodifiable({isConn: true, netType: ConnectivityResult.mobile});
        } else {
          mapCon = Map.unmodifiable({isConn: false, netType: ConnectivityResult.mobile});
        }
        break;
      case ConnectivityResult.none:   //* No Network: true !!
        mapCon = Map.unmodifiable({isConn: false, netType: ConnectivityResult.none});
        break;
    }
    return mapCon;
  }

}

Then you'd use this static function via a simple call from anywhere in your code as follows:

bool isConn; ConnectivityResult netType;
McGyver.checkInternetAccess().then(
  (mapCIA) {  //* 'mapCIA' == amalgamation for 'map' from 'CheckInternetAccess' function result.
    debugPrint("'mapCIA' Keys: ${mapCIA.keys}");
    isConn = mapCIA['isConnected'];
    netType = mapCIA['networkType'];
  }
);
debugPrint("Internet Access: $isConn   |   Network Type: $netType");

It's a pity that you have to link to TWO EXTERNAL PACKAGES to get this very basic functionality in your Flutter project - but I guess for now this is the best we have. I actually prefer the Data Connection Checker package over the Connectivity package - but (at the time of posting this) the former was missing that very important network identification feature that I require from the Connectivity package. This is the reason I defaulted onto this approach [ temporarily ].

SilSur
  • 495
  • 1
  • 6
  • 21
2

I have written a package to check the active internet connection and display a widget accordingly.

flutter_no_internet_widget

Example:

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

As per the network state, the appropriate widgets will be displayed. If you have an active internet connection an online widget will be displayed.

All the heavyweight is done by the package and all you have to do is provide online and offline widgets. Optionally you can provide a loading widget and lookup URL.

Discussion, PRs or suggestions are welcome.

internet-widget-video

Nagaraj Alagusundaram
  • 2,304
  • 2
  • 24
  • 31
1

late answer, but use this package to to check. Package Name: data_connection_checker

in you pubspec.yuml file:

dependencies:
    data_connection_checker: ^0.3.4

create a file called connection.dart or any name you want. import the package:

import 'package:data_connection_checker/data_connection_checker.dart';

check if there is internet connection or not:

print(await DataConnectionChecker().hasConnection);
Hekmat
  • 588
  • 6
  • 19
1

I used the data_connection_checker package to check the internet access even if the connection available by wifi or mobile, it works well: here is the code to check the connection:

bool result = await DataConnectionChecker().hasConnection;
if(result == true) {
   print('YAY! Free cute dog pics!');
} else {
   print('No internet :( Reason:');
   print(DataConnectionChecker().lastTryResults);
}

head over the package if you want more information. Data Connection Checker Package

1
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();
}
sanchit
  • 149
  • 2
  • 3
1

Based on this answer https://stackoverflow.com/a/68436867/10761151

If you used dart null safety you will get an error, so you can update the dependencies data_connection_checker: ^0.3.4 to internet_connection_checker: ^0.0.1+2

and you can use this code

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

and on the stateful widget you can implement this code

  bool hasInterNetConnection = false;

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

    super.initState();
  }

  void connectionChanged(dynamic hasConnection) {
    setState(() {
      hasInterNetConnection = hasConnection;
    });
  }
  • 1
    connectionChanged get called multiple times(=number of time I called initSate, i.e, every time the stateful widget is invoked). This happens even after I cancel the 'stream' in the 'dispose' method. How do I fix this? – Krishna Shetty Feb 14 '22 at 09:00
1

To check whether you have internet access or not, even if you are connected to wifi, use the below function.

Future<bool> checkInternetStatus() async {
    try {
      final url = Uri.https('google.com');
     var response = await http.head(url);
      if (response.statusCode == 200) {
        return true;
      } else {
        return false;
      }
    } catch (e) {
      return false;
    }
  }

also add http: ^0.13.5 dependency then import 'package:http/http.dart' as http;

Bahaa Hany
  • 744
  • 13
  • 22
0

Just trying to simplify the code using Connectivity Package in Flutter.

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
}
devDeejay
  • 5,494
  • 2
  • 27
  • 38
0

I having some problem with the accepted answer, but it seems it solve answer for others. I would like a solution that can get a response from the url it uses, so I thought http would be great for that functionality, and for that I found this answer really helpful. How do I check Internet Connectivity using HTTP requests(Flutter/Dart)?

David B.
  • 521
  • 1
  • 6
  • 18
0

For me I just create a single data in Firebase and use future builder to await for the data. Here, like this, you can check if the connection is too slow so the data will be loading:

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;
    },
  ),
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
0

You can make use of this package https://pub.dev/packages/flutter_network_connectivity

Underhood it makes use of NetworkCapabilities on Android and NetworkMonitor on iOS and listens to connectivity changes and pings to check internet availability, you can also configure to lookup internet availability in a periodic interval.

Add to your pubspec.yaml

flutter_network_connectivity: ^0.0.6

Create an Object

FlutterNetworkConnectivity flutterNetworkConnectivity =
    FlutterNetworkConnectivity(
      isContinousLookUp: true,  // optional, false if you cont want continous lookup
      lookUpDuration: const Duration(seconds: 5),  // optional, to override default lookup duration
      lookUpUrl: 'example.com',  // optional, to override default lookup url
);

and you can use its methods to check for network connectivity continuously or a call to check the current status

_flutterNetworkConnectivity.getInternetAvailabilityStream().listen((isInternetAvailable) {
  // do something
});

and register listener

await _flutterNetworkConnectivity.registerAvailabilityListener();

to check status on call

bool _isNetworkConnectedOnCall = await _flutterNetworkConnectivity.isInternetConnectionAvailable();
Praveen G
  • 794
  • 1
  • 13
  • 24
  • 1
    I think it is worth to mention that `flutter_network_connectivity` cannot be used for flutter web development. The mentioned library uses `dart:io` which can't be used in web built flutter applications. For further info please read the following github issue: https://github.com/thisisamir98/connection_status_bar/issues/3 – Wrench56 Mar 05 '22 at 19:54
0

final ConnectivityResult result = await Connectivity().checkConnectivity();

if (result == ConnectivityResult.wifi) {
  print('Connected to a Wi-Fi network');
} else if (result == ConnectivityResult.mobile) {
  print('Connected to a mobile network');
} else {
  print('Not connected to any network');
}
  • Use connectivity_plus package – Zeeshan Jun 02 '22 at 07:40
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – lemon Jun 02 '22 at 14:20
0

Use the observe_internet_connectivity package.

Available Features

  1. Check to know if a device has internet connection
  final hasInternet = await InternetConnectivity().hasInternetConnection;
  if (hasInternet) {
    //You are connected to the internet
  } else {
    //"No internet connection
  }
  1. Listen to internet connection changes via stream
  final subscription =
      InternetConnectivity().observeInternetConnection.listen((bool hasInternetAccess) {
        if(!hasInternetAccess){
          showToast('No Internet Connection');
        }
      });

   await Future.delayed(const Duration(seconds: 10 ));
   subscription.cancel();
  1. Use InternetConnectivityListener to listen to internet connectivity changes inside a flutter widget
    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(),
      ),
    );
  1. Use InternetConnectivityBuilder to build internet connection aware widgets
    return InternetConnectivityBuilder(
      connectivityBuilder: (BuildContext context, bool hasInternetAccess, Widget? child) { 
        if(hasInternetAccess) {
          return OnlineWidget();
        } else {
          return OfflineWidget();
        }
      },
      child: ChildWidget(),
    );
0

As this an old question a lot of things has be changed since last 5 years and connectivity_plus is no more working (at least for me) as I tried it today.

Luckily I found https://pub.dev/packages/internet_connection_checker which works like a charm, for checking internet connectivity.

As the author says the Purpose of the package:

The reason this package exists is that connectivity_plus package cannot reliably determine if a data connection is actually available. More info on its page here: https://pub.dev/packages/connectivity_plus

So recommend using internet_connection_checker and below code should work:

bool result = await InternetConnectionChecker().hasConnection;
if(result == true) {
  print('YAY! Free cute dog pics!');
} else {
  print('No internet :( Reason:');
  // print(InternetConnectionChecker().lastTryResults);
}

Best thing is its all dart, which is what flutter is based on.

vijay
  • 831
  • 9
  • 14
-1

The connectivity plugin states in its docs that it only provides information if there is a network connection, but not if the network is connected to the Internet. Use the below code and don't forget to use ".timeout()" because you can stuck forever using "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;
  }
}