J'utilise ce code pour vérifier sur Internet. et j'enveloppe également cette fonction dans initState. Le snack-bar s'affiche toujours lorsque Internet n'est pas disponible. Mais après la connexion à Internet, le snack-bar n'a pas disparu. Je ne peux pas utiliser le plugin de connectivité car ils ont dit sur Android, le plugin ne garantit pas la connexion à Internet.
checking1(TextEditingController usernameController, BuildContext context,
String _url, GlobalKey<ScaffoldState> _scaffoldKey) async {
try {
final result = await InternetAddress.lookup('google.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
usernameController.text == '' ?
showDialog(...some code...) :
usernameValidation(usernameController.text, context, _url);
}
}
on SocketException
catch (_) {
_showSnackBar(_scaffoldKey);
}
}
4 Réponses :
Le package connectivité fera ce que vous voulez. Il a un flux onConnectivityChanged auquel vous pouvez vous abonner. Cela informera votre application lorsque l'état de la connectivité change. Mais ce n'est pas parce que votre appareil est connecté à un réseau qu'il peut accéder à votre serveur et être connecté. Une recherche DNS serait donc une bonne idée avant de mettre à jour l'état interne de votre application.
https://pub.dartlang.org/documentation /connectivity/latest/connectivity/Connectivity-class.html
est-ce seulement une option?
Une autre option peut également être ce package: https://pub.dartlang.org/packages/flutter_offline qui traitent ce problème très simplement.
Vous devez d'abord importer le package 'package: flutter_offline / flutter_offline.dart';
Après cela, vous incluez OfflineBuilder sur la version Widget (BuildContext context) et il lira tous les changements de flux de ConnectivityResult en continu.
Comme l'exemple sur le lien ou comme le suivant
@override
Widget build(BuildContext context) {
return OfflineBuilder(
debounceDuration: Duration.zero,
connectivityBuilder: (
BuildContext context,
ConnectivityResult connectivity,
Widget child,
) {
if (connectivity == ConnectivityResult.none) {
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
),
body: Center(child: Text('Please check your internet connection!')),
);
}
return child;
},
child: Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text("Home")
),
body: new Column(
children: <Widget>[
new Container(
decoration: new BoxDecoration(color: Theme.of(context).cardColor),
child: _buildTxtSearchBox(),
),
new Divider(height: 10.0),
new FloatingActionButton.extended(
icon: Icon(Icons.camera_alt),
),
new Container(
...
),
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
drawer: MenuDrawer(),
)
);
}
cela a l'air bien, mais je ne comprends pas pourquoi il doit y avoir une propriété enfant au lieu de simplement renvoyer le widget à l'intérieur du générateur. de cette façon, tous les widgets peuvent accéder au résultat de la connectivité
Exemple complet démontrant à un auditeur la connectivité Internet et sa source.
import 'dart:async';
import 'dart:io';
import 'package:connectivity/connectivity.dart';
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: HomePage()));
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Map _source = {ConnectivityResult.none: false};
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.none:
string = "Offline";
break;
case ConnectivityResult.mobile:
string = "Mobile: Online";
break;
case ConnectivityResult.wifi:
string = "WiFi: Online";
}
return Scaffold(
appBar: AppBar(title: Text("Internet")),
body: Center(child: Text("$string", style: TextStyle(fontSize: 36))),
);
}
@override
void dispose() {
_connectivity.disposeStream();
super.dispose();
}
}
class MyConnectivity {
MyConnectivity._internal();
static final MyConnectivity _instance = MyConnectivity._internal();
static MyConnectivity get instance => _instance;
Connectivity connectivity = Connectivity();
StreamController 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');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
isOnline = true;
} else
isOnline = false;
} on SocketException catch (_) {
isOnline = false;
}
controller.sink.add({result: isOnline});
}
void disposeStream() => controller.close();
}
var result = wait Connectivity (). checkConnectivity (); me donnant une erreur comme "ConnectivityService: Ni l'utilisateur 11177 ni le processus actuel n'ont android.permission.ACCESS_NETWORK_STATE., null)" Quelqu'un peut-il aider?
@JayMungara Je ne parviens pas à obtenir l'erreur partielle, avez-vous ajouté l'autorisation ACCESS_NETWORK_STATE à votre fichier AndroidManifest.xml ?
@JayMungara Cela aiderait si vous pouviez partager la capture d'écran de l'erreur.
Consultez le problème ici github.com/flutter/flutter/issues/40731
@JayMungara Avez-vous exécuté mon code, est-ce que ça marche? Y voyez-vous une erreur? Et si oui, je serai heureux de vous aider sur Stackoverflow lui-même (pas Github), si vous pouvez poser une question, et partager son lien avec moi.
Pouvez-vous me dire quelle est la signification de cette opération "MyConnectivity._internal (); static final MyConnectivity _instance = MyConnectivity._internal ();" ?
@JayMungara C'est fait exprès pour nous assurer que nous avons une classe singleton MyConnectivity
Nous aurions pu le faire en utilisant statique final MyConnectivity _instance = MyConnectivity () je pense. droite?
@JayMungara Oui, vous pouvez le faire mais ce ne sera plus singleton, puisque vous pouvez facilement accéder au constructeur MyConnectivity () de l'extérieur.
Il est intéressant de voir comment le code ci-dessus ne ressemble pas à l'utilisation de l'argument résultat. Cela sert-il peut-être à faire des choses supplémentaires au résultat de la connectivité, mais n'est-il pas réellement nécessaire de faire une recherche avec?
Je trouve que cela est fiable et plus convaincant:
Future<bool> connectivityChecker() async {
var connected = false;
print("Checking internet...");
try {
final result = await InternetAddress.lookup('google.com');
final result2 = await InternetAddress.lookup('facebook.com');
final result3 = await InternetAddress.lookup('microsoft.com');
if ((result.isNotEmpty && result[0].rawAddress.isNotEmpty) ||
(result2.isNotEmpty && result2[0].rawAddress.isNotEmpty) ||
(result3.isNotEmpty && result3[0].rawAddress.isNotEmpty)) {
print('connected..');
connected = true;
} else {
print("not connected from else..");
connected = false;
}
} on SocketException catch (_) {
print('not connected...');
connected = false;
}
return connected;
}
Sur la base de la valeur booléenne de la connexion renvoyée, j'exécuterais une boucle basée sur une minuterie pour vérifier encore et encore la présence d'Internet jusqu'à ce que connecté. Ouvert à toutes les suggestions