如何在 Flutter 上持续检查互联网连接与否?
Posted
技术标签:
【中文标题】如何在 Flutter 上持续检查互联网连接与否?【英文标题】:How to continuously check internet connect or not on Flutter? 【发布时间】:2019-07-30 08:31:38 【问题描述】:我使用此代码检查互联网。我也将此函数包装到 initState 中。当互联网不可用时,小吃栏始终显示。但是连接到互联网后,小吃店并没有消失。我不能使用连接插件,因为他们在 android 上说,该插件不能保证连接到 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);
【问题讨论】:
【参考方案1】:演示互联网连接及其来源的侦听器的完整示例。
Original post
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 status = "Offline";
switch (_source.keys.toList()[0])
case ConnectivityResult.none:
status = "Offline";
break;
case ConnectivityResult.mobile:
status = "Mobile: Online";
break;
case ConnectivityResult.wifi:
status = "WiFi: Online";
break;
case ConnectivityResult.ethernet:
status = "Ethernet: Online";
break;
return Scaffold(
appBar: AppBar(title: Text("Internet")),
body: Center(child: Text(status)),
);
@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 结果 = await Connectivity().checkConnectivity();给我类似“ConnectivityService:用户 11177 和当前进程都没有 android.permission.ACCESS_NETWORK_STATE.,null)”之类的错误有人可以帮忙吗? @JayMungara 我无法得到部分错误,您是否已将ACCESS_NETWORK_STATE
权限添加到您的AndroidManifest.xml
文件中?
@JayMungara 如果您可以分享错误的屏幕截图会有所帮助。
在这里查看问题github.com/flutter/flutter/issues/40731
@JayMungara 你运行了我的代码,它工作了吗?您看到其中有任何错误吗?如果是,我很乐意在 *** 本身(不是 Github)上为您提供帮助,如果您可以提出问题并与我分享链接。【参考方案2】:
另一个选项也可以是这个包:https://pub.dartlang.org/packages/flutter_offline,它处理这个问题非常简单。
你需要先导入包'package:flutter_offline/flutter_offline.dart';
之后,您在 Widget 构建(BuildContext 上下文)中包含 OfflineBuilder,它将连续读取 ConnectivityResult 中的所有流更改。
喜欢链接上的例子或喜欢下面的例子
@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(),
)
);
【讨论】:
这看起来不错,但我很困惑为什么必须有一个子属性而不是仅仅在构建器中返回小部件。这样,所有小部件都可以访问连接结果【参考方案3】:connectivity 包可以满足您的需求。它有一个您可以订阅的onConnectivityChanged
流。这将在连接状态更改时通知您的应用。但仅仅因为您的设备连接到网络并不意味着它可以访问您的服务器并连接。因此,在更新应用程序的内部状态之前进行 DNS 查找是一个好主意。
https://pub.dartlang.org/documentation/connectivity/latest/connectivity/Connectivity-class.html
【讨论】:
这是唯一的选择吗?【参考方案4】:我认为这是可靠且更有说服力的:
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;
根据返回的连接的布尔值,我会运行一个基于计时器的循环来再次检查互联网,直到它连接。接受任何建议
【讨论】:
以上是关于如何在 Flutter 上持续检查互联网连接与否?的主要内容,如果未能解决你的问题,请参考以下文章