大家好,我是极客范的本期栏目编辑小友,现在为大家讲解Android检测是否连接互联网问题。
现在开发的应用不习惯网络,所以准确控制当前的网络状态尤为重要。经常有这样的场景:获取手机当前的网络类型,是否连接Wi-Fi,是否可以接入外部网络(互联网)。今天我们要讲的是如何判断手机是否可以和服务器通信。
注:本文所有代码均基于kotlin语言实现。
1.错误的方法。
在写代码之前,我们在网上搜索了主流的解决方案,发现大家的想法都是一样的:用NetworkInfo中的一个State是否连接来判断,结果却很残酷。这个方法是用来判断是否连接了Wi-Fi,但并不代表手机连接了互联网。但我也发布了代码供你参考:
2.正确的方法。
权限:
方案1: ping服务器地址(简单)。
通过ping命令的返回结果,我们可以知道是否连接到外部网络。现在主流有效的方法都是这个原理,但是大部分都是ping百度地址。这里建议使用8.8.8.8。示例代码如下:
PS:8.8.8.8是一个dns服务器地址,是谷歌提供的免费DNS服务器的IP地址。
该方案的优点是:
它可以在主线程上运行,并且是同步的。
快的
也有缺点:
它在一些旧手机上不起作用,比如银河S3,因为它与手机的代工有关。具体原因请参考:为什么ping在某些设备上有效,而在其他设备上无效?
方案二:连接服务器端口(推荐)。
使用socket连接到服务器的一个端口,通过连接结果判断手机是否连接到外部网络。推荐这种方法,因为它适用于所有安卓版本的手机,示例代码如下:
funi soline()=try { valtimeoutms=1500 socket()。使用{//连接的端口不同,网络协议也不同。DNS:53;http:80valsocketAddr=InetSocketAddress(' 8 . 8 . 8 . 8 ',53) it.connect(socketAddr,time out ms)} true } catch(e : Throwable){ false }
优点:
快,非常快。
方法包罗万象,没有恼人的版本适配。
缺点:
无法在主线程中运行。
方案三:根据域名获取IP(推荐)。
使用InetAddress提供的getByName()方法获取一个域名的IP地址,然后根据成功与否判断是否连接外部网络。建议使用这种方法。
优点:
快速和可定制的超时。
在主线程上运行。
采取所有版本。
缺点:
不
3.摘要
其实以上三种有效方案的思路都是一样的:
进行网络访问(您必须访问公共网络的地址,无论是域名还是IP地址)。
根据网络返回的结果。