How do you check internet ACCESS continously in flutter.dart, not connection

11,623

Solution 1

Here is the way you can build Network Aware applications

High level overview

  1. Create a service that listen to Connectivity change events, for
    example wifi, mobile and none (offline). This service will emit
    NewtorkStatus (our custom class) into a stream every time the
    Connectivity changes.

  2. Create consumer for the above NetworkStatus stream that will be
    notified everytime the NetworkStatus changes.

  3. Based on the network status rebuild the HomeScreen to show either
    online or offline contents.

Sounds tricky but its actually easy to implement, we will be using connectivity & provider package to our rescue.

Firstly configure our project to use above dependencies, edit pubspec.yaml to include the dependencies -

dependencies:
  flutter:
    sdk: flutter
  connectivity: ^3.0.6
  provider: ^6.0.1

Run $ pub get you synchronise all the dependencies.

Now we will create our own NewtorkStatusService this service will use NetworkStatus enumeration with two states Online & Offline to notify the Connectivity state.

network_status_service.dart

enum NetworkStatus { 
  Online, 
  Offline 
}

Now our NetworkStatusService will use the Connectivity package to get status of current connection status (wifi, mobile, none) and based on that it will emit a new NetworkStatus to stream. Our final NetworkStatusService would look something like this -

network_status_service.dart

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

enum NetworkStatus { Online, Offline }

class NetworkStatusService {
  StreamController<NetworkStatus> networkStatusController =
      StreamController<NetworkStatus>();

  NetworkStatusService() {
    Connectivity().onConnectivityChanged.listen((status){
      networkStatusController.add(_getNetworkStatus(status));
    });
  }

  NetworkStatus _getNetworkStatus(ConnectivityResult status) {
    return status == ConnectivityResult.mobile || status == ConnectivityResult.wifi ? NetworkStatus.Online : NetworkStatus.Offline;
  }
}

Now we will create our won custom widget that will return either an onlineChild or offlineChild based on NetworkStatus value. Here we will use provider package to get NetworkStatus. I would look something like this -

network_aware_widget.dart

import 'package:flutter/material.dart';
import 'package:flutter_network_aware_app/services/network_status_service.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';

class NetworkAwareWidget extends StatelessWidget {
  final Widget onlineChild;
  final Widget offlineChild;

  const NetworkAwareWidget({Key? key, required this.onlineChild, required this.offlineChild})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    NetworkStatus networkStatus = Provider.of<NetworkStatus>(context);
    if (networkStatus == NetworkStatus.Online) {
      return onlineChild;
    } else {
      _showToastMessage("Offline");
      return offlineChild;
    }
  }

  void _showToastMessage(String message){
    Fluttertoast.showToast(
        msg: message,
        toastLength: Toast.LENGTH_LONG,
        gravity: ToastGravity.BOTTOM,
        timeInSecForIosWeb: 1
    );
  }
}

Here I am also using the FlutterToast to show toast message (just to add some interactivity to app)

Now's the fun part we will bring all the pieces together to make our app respond to NetworkStatus value. We will use out custom made widget inside a StreamProvider widget. The StreamProvider will subscribe on the NewtorkStatusService networkStatusController stream and trigger a build on child components every time the NetworkStatus changes to Online or Offline. Here's how it will look -

home.dart

import 'package:flutter/material.dart';
import 'package:flutter_network_aware_app/services/network_status_service.dart';
import 'package:flutter_network_aware_app/ui/components/network_aware_widget.dart';
import 'package:provider/provider.dart';

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text("Network Aware App"),
      ),
      body: StreamProvider<NetworkStatus>(
        create: (context) =>
            NetworkStatusService().networkStatusController.stream,
        child: NetworkAwareWidget(
          onlineChild: Container(
            child: Center(
              child: Text(
                "I am online",
                style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.w600),
              ),
            ),
          ),
          offlineChild: Container(
            child: Center(
              child: Text(
                "No internet connection!",
                style: TextStyle(
                    color: Colors.grey[400],
                    fontWeight: FontWeight.w600,
                    fontSize: 20.0),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

As you can see we are wrapping our NetworkAwareWidget inside a StreamProvider of NetworkStatus. StreamProvider also makes sure that on create it will subscribe to the NetworkStatusService controller stream.

Finally our app starting point main.dart will look something like this -

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_network_aware_app/ui/screens/home_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        debugShowCheckedModeBanner: false,
        theme: ThemeData.dark().copyWith(primaryColor: Colors.blue),
        home: Home());
  }
}

The application would work as follows -

Online Offline Demo

I hope this helps you to build you own network aware app and components!

Solution 2

You can use this https://pub.dev/packages/connectivity_widget . By installing this package use this code in your build function.

ConnectivityWidget(
        builder: (context, isOnline) => Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text("${isOnline ? 'Online' : 'Offline'}", style: TextStyle(fontSize: 30, color: isOnline ? Colors.green : Colors.red),),
              SizedBox(height: 20,),
              Text(
                'Number of times we connected to the internet:',
              ),
              Text(
                '$_counter',
                style: Theme.of(context).textTheme.display1,
              ),
            ],
          ),
        )

Solution 3

connectivity package is just for discovering network connectivity. if you want to be sure about internet access you can use data_connection_checker.

Solution 4

You can use this alternative, without using any packages. Call this function whenever you need to check internet connectivity

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

}

Share:
11,623
John
Author by

John

Updated on June 04, 2022

Comments

  • John
    John almost 2 years

    how do you continously check internet access? I was able to show if wifi is connectected or mobile data. However, not all connection would have internet access.

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

    This is currently the code im using. I was hoping how someone could check continously of internet access?