Home > Mobile >  how to await for network connectivity status in flutter
how to await for network connectivity status in flutter

Time:08-16

I have used connectivity_plus and internet_connection_checker packages to check the internet connectivity.

The problem occured is , the app works perfectly fine as expected when the app start's with internet on state. But when the app is opened with internet off, the dialog isn't shown !!

I assume this is happening because the build method is called before the stream of internet is listened.

Code :

class _HomePageState extends State<HomePage> {
  late StreamSubscription subscription;
  bool isDeviceConnected = false;
  bool isAlertSet = false;

  @override
  void initState() {
    getConnectivity();
    super.initState();
  }

  getConnectivity() {
    subscription = Connectivity().onConnectivityChanged.listen(
      (ConnectivityResult result) async {
        isDeviceConnected = await InternetConnectionChecker().hasConnection;
        if (!isDeviceConnected && isAlertSet == false) {
          showDialogBox();
          setState(() {
            isAlertSet = true;
          });
        }
      },
    );
  }

  @override
  void dispose() {
    subscription.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      ...
    );
  }

  showDialogBox() => showDialog(/* no internet dialog */)

Extending the question: Is it assured that this works for all the pages ?

  • if yes, how ?
  • if not , how to overcome this?

CodePudding user response:

  1. First of all you need to listen for internet connectivity in your app first screen which is probably app.dart

     GlobalKey<NavigatorState> navigatorKey = GlobalKey();
    
     final noInternet = NoInternetDialog();
    
     class TestApp extends StatefulWidget {
      @override
      State<TestApp> createState() => _TestAppState();
      }
    
     class _TestAppState extends State<TestApp> {
      @override
      void initState() {
        super.initState();
        checkInternetConnectivity();
       }
    
     @override
     Widget build(BuildContext context) {
      return MaterialApp(...);
     }
    
    Future<void> checkInternetConnectivity() async {
      Connectivity().onConnectivityChanged.getInternetStatus().listen((event) 
       {
       if (event == InternetConnectionStatus.disconnected) {
         if (!noInternet.isShowing) {
           noInternet.showNoInternet();
         }
       }
       });
      }
     }
    
  2. Make the screen stateful in which you are calling MaterialApp and in initState of that class check for your internet connection, like above

  3. You are saying how can I show dialog when internet connection changes for that you have to create a Generic class or extension which you can on connectivity change. You have to pass context to that dialogue using NavigatorKey

    class NoInternetDialog {
     bool _isShowing = false;
     NoInternetDialog();
    
     void dismiss() {
      navigatorKey.currentState?.pop();
      }
    
      bool get isShowing => _isShowing;
    
      set setIsShowing(bool value) {
     _isShowing = value;
     }
    
     Future showNoInternet() {
      return showDialog(
       context: navigatorKey.currentState!.overlay!.context,
       barrierDismissible: true,
       barrierColor: Colors.white.withOpacity(0),
       builder: (ctx) {
         setIsShowing = true;
         return AlertDialog(
           elevation: 0,
           backgroundColor: Colors.transparent,
           insetPadding: EdgeInsets.all(3.0.h),
           content: Container(...),
         );
       },
      );
     }
    }
    

CodePudding user response:

Use checkConnectivity to check current status. Only changes are exposed to the stream.

final connectivityResult = await Connectivity().checkConnectivity();
  • Related