Flutter 检测是否已连接到互联网?
文章目录
connectivity
这个插件允许Flutter应用发现网络连接并相应地配置自己。它可以区分蜂窝网络连接和WiFi连接。这个插件适用于iOS和Android。
注意,在Android上,这并不能保证连接到互联网。例如,该应用程序可能有wifi接入,但它可能是一个无法接入的VPN或旅馆wifi。
用法
///用于检查当前状态的示例用法
import 'package:connectivity/connectivity.dart';
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
// I am connected to a mobile network.
} else if (connectivityResult == ConnectivityResult.wifi) {
// I am connected to a wifi network.
}
不过应该注意:
不应该使用当前网络状态来决定是否可以可靠地建立网络连接。始终保护您的应用程序代码,防止可能来自网络层的超时和错误。
也可以通过订阅连接插件暴露的流来监听网络状态变化:
import 'package:connectivity/connectivity.dart';
@override
initState() {
super.initState();
subscription = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
// Got a new connectivity status!
})
}
// Be sure to cancel subscription after you are done
@override
dispose() {
super.dispose();
subscription.cancel();
}
不过,从Android O开始,连接改变不再在后台通知Android应用程序。当你的应用程序被恢复时,你应该经常检查连接状态。广播只有在应用程序位于前台时才有用。
你可以使用以下方式获取有关wi-fi的资料:
import 'package:connectivity/connectivity.dart';
var wifiBSSID = await (Connectivity().getWifiBSSID());
var wifiIP = await (Connectivity().getWifiIP());network
var wifiName = await (Connectivity().getWifiName());wifi network
检测网络可用
既然connecty不能确定是否连接网络,那就这样:
/// 如果已连接热点或VPN,此时断开根热点或VPN,此种方法也会返回true
static Future<bool> checkInternet() async {
bool connectionStatus;
try {
String host = "google.com"; //判断国内外,谷歌还是百度
host = "baidu.com";
final result = await InternetAddress.lookup(host);
print("result-- $result");
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
connectionStatus = true;
print("connected $connectionStatus");
}
} on SocketException catch (_) {
connectionStatus = false;
print("not connected $connectionStatus");
}
return connectionStatus;
}
lookup:查找一个主机,返回一个InternetAddress列表,如
[InternetAddress('39.156.69.79', IPv4), InternetAddress('220.181.38.148', IPv4)]
确实,此种方法直连移动数据或wifi是没问题,原本以为达到目的了.
可是经过试验,在设备A已连接B设备热点或VPN情况下,此时断开B的热点或VPN,此方法也会返true,懵…
想找到清除InternetAddress的方法,有找到的同学告知我一下,
考虑过用Socket连接,高射炮架起来,看到了Socket connect的注释,它也会lookup,那和上面的有啥区别
[host] can either be a [String] or an [InternetAddress]. If [host] is a
* [String], [connect] will perform a [InternetAddress.lookup] and try
* all returned [InternetAddress]es, until connected. Unless a
* connection was established, the error from the first failing connection is
* returned.
继续往下看:
The argument [timeout] is used to specify the maximum allowed time to wait
* for a connection to be established. If [timeout] is longer than the system
* level timeout duration, a timeout may occur sooner than specified in
* [timeout]. On timeout, a [SocketException] is thrown and all ongoing
* connection attempts to [host] are cancelled.
翻译:参数[timeout]用于指定允许等待的最大时间 用于建立连接。如果[timeout]比系统水平超时时间长,超时可能比指定的timeout更早发生。一旦超时,抛出一个[SocketException],所有在进行中的连接[host]的尝试都会被取消。
原来可以用超时来解决这个…
哈,算了,我还是用dio 处理SocketExceotion吧
static String getFinalException(DioError dioError) {
print("HandleError DioError: $dioError");
switch (dioError.type) {
case DioErrorType.CANCEL:
return "Request Cancel";
case DioErrorType.CONNECT_TIMEOUT:
return "CONNECT TIMEOUT";
case DioErrorType.SEND_TIMEOUT:
return 'Send Time Out';
case DioErrorType.RESPONSE:
return "Server Incorrect Status";
case DioErrorType.RECEIVE_TIMEOUT:
return "Receive Time Out";
case DioErrorType.DEFAULT:
String msg = 'UnKnown';
Log.v("Handle Error DEFAULT", dioError.error);
if (dioError.error != null) {
if (dioError.error is SocketException) {
msg = "网络连接异常";
} else {
msg = dioError.message;
}
}
return msg;
}
return "UnKnown";
}