Check whether there is an Internet connection available on Flutter app Check whether there is an Internet connection available on Flutter app dart dart

Check whether there is an Internet connection available on Flutter app


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


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 utilityimport 'dart:async'; //For StreamController/Streamimport '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


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:

    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 and Günter Zöchbauer