174 votes

Vérifiez si une connexion Internet est disponible sur l'application Flutter.

J'ai un appel réseau à exécuter. Mais avant cela, je dois vérifier si l'appareil a une connectivité internet.

Voici ce que j'ai fait jusqu'à présent :

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

La méthode ci-dessus ne fonctionne pas.

303voto

Günter Zöchbauer Points 21340

Le site connectivité Le plugin indique dans sa documentation qu'il ne fournit des informations que s'il existe une connexion réseau, mais pas si le réseau est connecté à Internet.

Notez que sur Android, cela ne garantit pas la connexion à Internet. Par exemple, l'application peut avoir un accès wifi mais il peut s'agir d'un VPN ou du WiFi d'un hôtel sans accès.

Vous pouvez utiliser

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

3 votes

Je reçois l'erreur "isNotEmpty n'est pas déclaré dans InternetAddress".

0 votes

Ups, j'ai déjà supprimé le code localement, mais je pense qu'il devrait être result[0].rawAddress.isNotEmpty . Désolé pour ça.

0 votes

J'obtiens des erreurs sur ce code ainsi que sur ` on SocketException catch(_) ` . Dit on est indéfinie.

109voto

dennmat Points 703

Pour tous ceux qui atterrissent ici, j'aimerais ajouter à la réponse de Günter Zöchbauer qu'il s'agissait de ma solution pour mettre en œuvre un utilitaire permettant de savoir s'il y a Internet ou non, indépendamment de toute autre chose.

Avis de non-responsabilité :

Je suis novice à la fois dans Dart et Flutter, donc ce n'est peut-être pas la meilleure approche, mais j'aimerais bien avoir des retours.


Combinaison de flutter_connectivity et du test de connexion de Günter Zöchbauer

Mes exigences

Je ne voulais pas avoir un tas de code répété partout où j'avais besoin de vérifier la connexion et je voulais qu'il mette automatiquement à jour les composants ou tout autre élément qui s'occupe de la connexion à chaque fois qu'il y avait un changement.

ConnectionStatusSingleton

D'abord, on installe un Singleton. Si vous n'êtes pas familier avec ce modèle, il y a beaucoup d'informations intéressantes en ligne à son sujet. Mais l'essentiel est que vous voulez créer une seule instance d'une classe pendant le cycle de vie de l'application et être capable de l'utiliser n'importe où.

Ce singleton s'accroche à flutter_connectivity et écoute les changements de connectivité, puis teste la connexion réseau, puis utilise une StreamController pour mettre à jour tout ce qui compte.

Ça ressemble à ça :

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

Utilisation

Initialisation

Tout d'abord, nous devons nous assurer que nous appelons l'initialisation de notre singleton. Mais seulement une fois. C'est à vous de voir, mais je l'ai fait dans mon application. 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();   
}

Sur Widget ou ailleurs

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

J'espère que quelqu'un d'autre trouvera cela utile !


Exemple de dépôt github : https://github.com/dennmat/flutter-connectiontest-example

Passez en mode avion dans l'émulateur pour voir le résultat.

0 votes

J'ai mis le premier code dans Main.dart et j'ai essayé avec une HomePage, mais cela donne l'erreur suivante Could not load source 'dart:async/broadcast_stream_controller.dart' : <source non disponible>.

0 votes

Il y a probablement une autre erreur et c'est juste l'éditeur qui essaie d'ouvrir le fichier mais il n'y a pas accès. J'ai modifié cet exemple à partir de mon code pour le généraliser. J'ai peut-être cassé quelque chose. Je vérifierai quand je serai de retour chez moi. Mais si vous regardez le panneau de débogage, pouvez-vous trouver la véritable erreur ?

3 votes

J'ai testé le code et il fonctionne pour moi. J'aurais besoin de plus d'informations pour vous aider.

78voto

CopsOnRoad Points 4705

Null Code de sécurité :

  • Contrôle unique :

    Créez cette méthode :

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

    Utilisation :

    bool isOnline = await hasNetwork();
  • Configuration d'un écouteur :

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

Capture d'écran :

enter image description here

Crédit à : <a href="https://pub.dev/packages/connectivity" rel="nofollow noreferrer">connectivité </a>et Günter Zöchbauer

0 votes

Via firebase, SDK est-ce possible ?

0 votes

@LOG_TAG Vous n'avez pas besoin d'utiliser Firebase pour cela.

0 votes

Map _source = {ConnectivityResult.none : false} ; Pourquoi avez-vous utilisé "false" ici ?

24voto

Tushar Pandey Points 417

Utilisation de

dependencies:
  connectivity: ^0.4.2

ce que nous avons obtenu de ressources est

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

Le futur est un peu problématique pour moi, nous devons l'implémenter à chaque fois comme :

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

Pour résoudre ce problème, j'ai créé une classe qui accepte une fonction avec le paramètre booléen isNetworkPresent comme ceci

methodName(bool isNetworkPresent){}

Et la classe utilitaire est

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

Et pour utiliser l'utilitaire connectivity-check

  fetchPrefrence(bool isNetworkPresent) {
    if(isNetworkPresent){

    }else{

    }
  }

Je vais utiliser cette syntaxe

NetworkCheck networkCheck = new NetworkCheck();
networkCheck.checkInternet(fetchPrefrence)

7voto

kristiyan.mitev Points 163

J'ai créé un paquet qui (je pense) résout ce problème de manière fiable.

Le paquet sur pub.dev

Le paquet sur GitHub

La discussion est la bienvenue. Vous pouvez utiliser le traqueur de problèmes sur GitHub.


Je ne pense plus que ce ci-dessous soit une méthode fiable :


Vous voulez ajouter quelque chose à @Oren's réponse : vous devriez vraiment ajouter un catch supplémentaire, qui attrapera toutes les autres exceptions (juste pour être sûr), OU supprimer complètement le type d'exception et utiliser un catch, qui traite toutes les exceptions :

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

ou encore plus simple...

Cas 2 :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X