#4 My Learnings: Checking Internet Connectivity of Device inside Flutter Application...

#4 My Learnings: Checking Internet Connectivity of Device inside Flutter Application...

ยท

8 min read

Intro

Say we open our application, & start running it & after some time say the wifi network gets disconnected or there comes some network issue, & the internet stops working. The app is still running with the preloaded data but we could easily notice one thing, the application itself notifies us with a message on the screen or some alert dialogue or some snack bar... with a text saying something similar to, "No internet connection, please check your network". That means in some way or another the applications we use can communicate with the device to know its network-like statuses... isn't that amazing? it is indeed & that's what we are going to discuss today i.e. we are going to check the internet connectivity of your device inside our Flutter application. Hushhh! finally done with the intro ๐Ÿ™‚, how do you guys come up with a new intro each time yaar?

I've got one thing for sure i.e. if I've to keep the blog simple & concise then I can't explain the basics every time cause the basic stuff like creating a new Flutter app or removing the boilerplate code, takes valuable reading time for the user & hence lost the interest also the blog becomes bigger & bigger. So, from now onwards I'll be assuming that you are aware of the basics. Don't worry I will still be adding necessary links for reference so that there won't be any problem for a complete beginner.

Project Overview

At the end of this project, we want to show the internet connectivity status of the device on the screen with a message in the center & appropriate color in the background. I won't be working much on the UI side& state management as it will extend the blog & the main concept will be left behind. You can build the UI in terms of alert dialogue or snack bar as you want. The project will look like the image shared below at the end.

Prerequisites

The prerequisites for the project are listed below,

  1. Flutter SDK setup with Android Studio/ VScode

  2. Being able to create basic flutter project

  3. Understanding of Flutter, dart & concepts like streams & stream builder.

That's all you wanna know to execute the project. Click here to understand these concepts in detail.

Project Work

Setting up the environment

First of all, create a new flutter project if you don't have an existing one for implementing this feature. Also, remove the boilerplate code. To complete both these things revisit my blog which includes doing this by clicking here.

Create a new dart file

Now that we've cleared the boilerplate, we will create a new file named internet_status.dart inside the lib folder of project as shown below,

Open the file & create a stateful widget class named InternetStatus as we will be changing the state of the widget whenever & wherever necessary, the code for the same is given below,

import 'package:flutter/material.dart';
class InternetStatus extends StatefulWidget {
  const InternetStatus({Key? key}) : super(key: key);
  @override
  State<InternetStatus> createState() => _InternetStatusState();
}
class _InternetStatusState extends State<InternetStatus> {
  @override
  Widget build(BuildContext context) {
    return Scaffold();
  }
}

Set home to internet_status.dart

Open the main.dart file & replace the home of the MyApp with InternetStatus() so that we could see the implementation on the very first page of the application.

Install the Connectivity_plus plugin

Open the terminal in the code editor, ensure you are in the project directory so that you could run the commands, then run the command "flutter pub add connectivity_plus" to install the Connectivity_plus plugin which we will be needing to check the internet connectivity of the device.

Import the connectivity_plus plugin

Open the interner_status.dart file, inside it, import the connectivity_plus plugin by adding the below import statement,

import 'package:connectivity_plus/connectivity_plus.dart';

Once we are done with importing, it's time to use the plugin, about which I would like you to know the process by which we're going to use it,

Understanding the logic behind

As we know whenever the user turns off the internet or there comes an internet issue, we should listen to that info & notify the user accordingly. The best way to achieve that functionality is by using Streams & Stream-Builder as they are known to implement real-time fluctuating data. Now, the connectivity_plus plugin uses stream in its implementation to get the internet connectivity status in real-time, & therefore we can just use that stream in our stream-builder to show the info on the screen.

Creating a StreamBuilder

As we've discussed, let's create a StreamBuilder at the scaffold body of the internet_status.dart file, with the required builder function as shown below. We can see three conditions that are very common to handle in FutureBuilder as well as in StreamBuilder,

  1. snapshot.hasData: When the stream has been successfully listened to & we get the data

  2. snapshot.hasError: When we get some error while listening to the stream

  3. In the else part, the case is when there's no data i.e. we're listening to the stream but the data is yet to come, we show a loading indicator for that period in general.

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.white,
    body: StreamBuilder(
      builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
       if (snapshot.hasData){
          return Text('has data');
        }else if (snapshot.hasError){
          return AlertDialog(
            scrollable: true,
            title: const Text('Error Occurred: '),
            content: Text('${snapshot.error}'),
            actions: [
              TextButton(
                  onPressed: (){
                    Navigator.of(context).pop();
                  },
                  child: const Text('Ok'))
            ],
          );
        }else{
          return const Center(
            child: SizedBox(
              height: 60,
              width: 60,
              child: CircularProgressIndicator(),
            ),
          );
        }
      },
    )
  );
}

Add Connectivity_plus stream to the StreamBuilder

Now, the most important part of the process i.e. to listen to the connectivity_plus stream**(Connectivity().onConnectivityChanged)** whenever there's a change of network status & that we will be doing by adding it to the stream property of StreamBuilder as shown below,

body: StreamBuilder(
  stream: Connectivity().onConnectivityChanged,
  builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {

  },
)

Congratulations! from now on whenever the connectivity status changes, we will be able to listen to it & be able to change the UI accordingly with the help of the builder of StreamBuilder. let's handle the UI,

Showing Connectivity status on the Screen

We will be getting the internet status like ConnectivityResult.none if there's no internet connectivity, ConnectivityResult.mobile when we will be using mobile data, ConnectivityResult.wifi when we will be using a Wi-Fi network & so on. If we observe the status carefully, we could say that the term after "." is the actual connectivity status so we will format that info with the code snippet below,

var status = snapshot.data.toString().split('.')[1];

Now, in the snapshot.hasData condition, we will be showing the connectivity status with the two conditions mentioned below,

  1. if status == "none"

    i.e. no connectivity, in this case, we will display a message on the screen saying "No Internet Connection" with a red background.

  2. else

    i.e. device connected with mobile/wifi or any other network. In this case, we will display a message on the screen with the network type saying 'Internet Connected with mobile/wifi' with a green background.

These two conditions are handled in the code snippet below,

if (snapshot.hasData){
  var status = snapshot.data.toString().split('.')[1];
  if (status == 'none'){
    return Center(
      child: Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        color: Colors.red,
        child: Center(
            child: Text('No Internet Connection',
              style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white),
            ),
        ),
      ),
    );
  }else{
    return Center(
      child: Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        color: Colors.green,
        child: Center(
            child: Text('Internet Connected with $status',
              style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white),
            ),
        ),
      ),
    );
  }
}

Final Code View

If you've followed all the steps & added the code exactly where it has to be, the application should work fine & give you the output on the screen. If you are still having any errors then please check your code line by line with the codebase shared below & try running the app again, it should work fine.

main.dart

import 'package:flutter/material.dart';
import 'internet_status.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const InternetStatus(),
    );
  }
}

internet_status.dart

import 'package:flutter/material.dart';
import 'package:connectivity_plus/connectivity_plus.dart';

class InternetStatus extends StatefulWidget {
  const InternetStatus({Key? key}) : super(key: key);

  @override
  State<InternetStatus> createState() => _InternetStatusState();
}

class _InternetStatusState extends State<InternetStatus> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: StreamBuilder(
      stream: Connectivity().onConnectivityChanged,
      builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
        if (snapshot.hasData){
          var status = snapshot.data.toString().split('.')[1];
          if (status == 'none'){
            return Center(
              child: Container(
                height: MediaQuery.of(context).size.height,
                width: MediaQuery.of(context).size.width,
                color: Colors.red,
                child: Center(
                    child: Text('No Internet Connection',
                      style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white),
                    ),
                ),
              ),
            );
          }else{
            return Center(
              child: Container(
                height: MediaQuery.of(context).size.height,
                width: MediaQuery.of(context).size.width,
                color: Colors.green,
                child: Center(
                    child: Text('Internet Connected with $status',
                      style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white),
                    ),
                ),
              ),
            );
          }

        }else if (snapshot.hasError){
          return AlertDialog(
            scrollable: true,
            title: const Text('Error Occurred: '),
            content: Text('${snapshot.error}'),
            actions: [
              TextButton(
                  onPressed: (){
                    Navigator.of(context).pop();
                  },
                  child: const Text('Ok'))
            ],
          );
        }else{
          return const Center(
            child: SizedBox(
              height: 60,
              width: 60,
              child: CircularProgressIndicator(),
            ),
          );
        }
      },
        )
    );
  }
}

Outro

Hurray! Another amazing learning session for me, writing blogs helps me understand the concepts that I wouldn't have focused on if I had just been implementing the code, so, I understand now why blogging is said to be a better learning experience for the creator himself. I am enjoying the learning process & trying to improve every day, what about you? Are you guys enjoying the content? let me know of any improvements...

so, hello all, I am Rushikesh & this is a short flutter project with one of the powerful concepts used widely. Have fun learning, & will catch you in the next one... till then it's a farewell.

ย