如何检查 Android 上的互联网访问情况? InetAddress 永不超时
我有一个 AsyncTask 应该检查对主机名的网络访问。但 doInBackground()
永远不会超时。有人知道吗?
public class HostAvailabilityTask extends AsyncTask<String, Void, Boolean> {
private Main main;
public HostAvailabilityTask(Main main) {
this.main = main;
}
protected Boolean doInBackground(String... params) {
Main.Log("doInBackground() isHostAvailable():"+params[0]);
try {
return InetAddress.getByName(params[0]).isReachable(30);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean... result) {
Main.Log("onPostExecute()");
if(result[0] == false) {
main.setContentView(R.layout.splash);
return;
}
main.continueAfterHostCheck();
}
}
I got a AsyncTask
that is supposed to check the network access to a host name. But the doInBackground()
is never timed out. Anyone have a clue?
public class HostAvailabilityTask extends AsyncTask<String, Void, Boolean> {
private Main main;
public HostAvailabilityTask(Main main) {
this.main = main;
}
protected Boolean doInBackground(String... params) {
Main.Log("doInBackground() isHostAvailable():"+params[0]);
try {
return InetAddress.getByName(params[0]).isReachable(30);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean... result) {
Main.Log("onPostExecute()");
if(result[0] == false) {
main.setContentView(R.layout.splash);
return;
}
main.continueAfterHostCheck();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
您可以使用此方法来检测网络可用性 -
You can use this method to detect network availability-
此方法使您可以选择一种非常快的方法(用于实时反馈)或一种较慢的方法(用于需要可靠性的一次性检查)
This method gives you the option for a really fast method (for real time feedback) or a slower method (for one off checks that require reliability)
Android 文档中对此进行了介绍
http://developer.android.com/training/monitoring-device -state/connectivity-monitoring.html
This is covered in android docs
http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html
检查我们是否与 isAvailable() 以及是否可以与 isConnected()
并且您可以确定活动网络的类型 WiFi :
或移动 Móvil :
不要忘记权限:
Very important to check if we have connectivity with isAvailable() and if is possible to establish a connection with isConnected()
and you can derterminate the type of network active WiFi :
or mobile Móvil :
don´t forget the permissions:
检查 Android 网络/互联网连接状态并不复杂。下面的
DetectConnection
类将帮助您检查此状态:有关更多详细信息,请访问
如何检查 Android 网络/互联网连接状态
It is not complex to check Android network / internet connectivity status. The below
DetectConnection
class will help you to check this status:For more details visit
How to Check Android Network / Internet Connectivity Status
以下是我的
Utils
类中的代码:Following is the code from my
Utils
class:我已经应用了 @Levit 提供的解决方案并创建了不会调用额外 Http 请求的函数。
它将解决错误
无法解析主机
现在这样称呼它,
I have applied the solution provided by @Levit and created function that will not call the extra Http Request.
It will solve the error
Unable to Resolve Host
Now call it like,
更新2015年6月29日
如果您使用 Xamarin.Android 并想要检查连接性,则可以使用 Nuget 包,它可以在多个平台上提供此功能。好的候选者是 此处和此处。
[更新结束]
上面的答案都很好,但它们都是用Java编写的,而且几乎都检查连接性。就我而言,我需要与特定类型的连接建立连接,并且我正在 Xamarin.Android 上进行开发。此外,我没有在硬件层中传递对我的活动上下文的引用,我使用应用程序上下文。这是我的解决方案,以防有人有类似的要求。不过,我还没有完成完整的测试,完成测试后将更新答案
Update 29/06/2015
If you are using Xamarin.Android and want to check for connectivity, you can use a Nuget package that would give you this functionality on multiple platforms. Good candidates are here and here.
[End of Update]
The Answers above are quite good, but they are all in Java, and almost all of them check for a connectivity. In my case, I needed to have connectivity with a specific type of connection and I am developing on Xamarin.Android. Moreover, I do not pass a reference to my activities Context in the Hardware layer, I use the Application Context. So here is my solution, in case somebody comes here with similar requirements. I have not done full testing though, will update the answer once I am done with my testing
使用 ConnectivityManager 的其他答案是错误的,因为拥有网络连接并不意味着您可以访问互联网。例如,用户可能已连接到咖啡店的 WiFi 门户,但无法访问互联网。要检查互联网是否可以访问,您必须尝试连接到实际的服务器。通常,当您想要执行此操作时,您会想到要连接到的特定服务器,因此请继续检查是否可以连接到该服务器。这是检查服务器连接的简单方法。
设置 ConnectTimeout 的原因是否则它默认为 TCP 超时,该超时可能会持续很多秒。
另请注意,Android 不允许您在主线程上运行它。
The other answers that use ConnectivityManager are wrong because having a network connection doesn't mean you have internet access. For example, the user might be connected to a coffee shop's WiFi portal but can't get to the internet. To check that the internet is accessible you have to try to connect to an actual server. Normally when you want to do this you have a specific server in mind that you want to connect to, so go ahead and check if you can connect to that server. Here's a simple method for checking connectivity to a server.
The reason for setting the ConnectTimeout is that otherwise it defaults to the TCP timeout which can be many seconds long.
Note also that Android won't let you run this on your main thread.
我已经浏览了所有答案,并提出了自己的答案,首先检查互联网是否可用,如果互联网可用,则检查它是否处于活动状态。
我已经包含了所有必要的方法和类来检查活动的互联网连接。
NetworkUtils.class
您可以使用以下代码检查互联网是否处于活动状态:
I have gone through all the answers and i come up with my own answer which first check whether Internet is available and if Internet is available then it check whether it is active or not.
I have included all necessary method and classes to check for active Internet connection.
NetworkUtils.class
You can check whether Internet is active using below code:
如果设备处于飞行模式(或者可能在没有可用网络的其他情况下),
cm.getActiveNetworkInfo()
将为null
,因此您需要添加 <代码>空检查。修改如下(Eddie 的解决方案):
另外将以下权限添加到
AndroidManifest.xml
:一还有一点,如果您在给定时间点绝对需要网络连接,那么最好使用
netInfo.isConnected()
而不是netInfo.isConnectedOrConnecting
。我想这取决于个人用例。If the device is in airplane mode (or presumably in other situations where there's no available network),
cm.getActiveNetworkInfo()
will benull
, so you need to add anull
check.Modified (Eddie's solution) below:
Also add the following permission to the
AndroidManifest.xml
:One other small point, if you absolutely need a network connection at the given point in time, then it might be better to use
netInfo.isConnected()
rather thannetInfo.isConnectedOrConnecting
. I guess this is up to the individual use-case however.网络连接/互联网访问
isConnectedOrConnecting()
(在大多数答案中使用)检查任何网络连接A) Ping a Server(简单)
+
可以在主线程上运行-
在某些旧设备(Galays S3 等)上不起作用,如果没有互联网可用,它会阻塞一段时间。B) 连接到互联网上的套接字(高级)
+
非常快(无论哪种方式),适用于所有设备,非常可靠-
可以不在 UI 线程上运行这在每个设备上都非常可靠,并且速度非常快。但它需要在单独的任务中运行(例如
ScheduledExecutorService
或AsyncTask
)。可能的问题
它真的足够快吗?
是的,非常快;-)
除了在互联网上测试某些内容之外,是否没有可靠的方法来检查互联网?
据我所知,没有,但请告诉我,我会编辑我的答案。
如果 DNS 关闭怎么办?
Google DNS(例如
8.8.8.8
)是世界上最大的公共DNS。截至 2018 年,它每天处理超过一万亿个查询 [1]。这么说吧,您的应用程序可能不会成为今天的话题。需要哪些权限?
只是互联网访问 - 惊喜^^(顺便说一句,您有没有想过,这里建议的一些方法甚至可以在没有此许可的情况下对互联网访问进行远程粘合?)
额外:一次性
RxJava/RxAndroid
示例 (Kotlin)额外:一次性
RxJava/RxAndroid
示例 (Java)额外:一次性
AsyncTask
示例注意:这显示了如何执行请求的另一个示例。然而,由于
AsyncTask
已被弃用,它应该被应用程序的线程调度、Kotlin Coroutines、Rx 等取代。Network connection / Internet access
isConnectedOrConnecting()
(used in most answers) checks for any network connectionA) Ping a Server (easy)
+
could run on main thread-
does not work on some old devices (Galays S3, etc.), it blocks a while if no internet is available.B) Connect to a Socket on the Internet (advanced)
+
very fast (either way), works on all devices, very reliable-
can't run on the UI threadThis works very reliably, on every device, and is very fast. It needs to run in a separate task though (e.g.
ScheduledExecutorService
orAsyncTask
).Possible Questions
Is it really fast enough?
Yes, very fast ;-)
Is there no reliable way to check internet, other than testing something on the internet?
Not as far as I know, but let me know, and I will edit my answer.
What if the DNS is down?
Google DNS (e.g.
8.8.8.8
) is the largest public DNS in the world. As of 2018 it handled over a trillion queries a day [1]. Let 's just say, your app would probably not be the talk of the day.Which permissions are required?
Just internet access - surprise ^^ (Btw have you ever thought about, how some of the methods suggested here could even have a remote glue about internet access, without this permission?)
Extra: One-shot
RxJava/RxAndroid
Example (Kotlin)Extra: One-shot
RxJava/RxAndroid
Example (Java)Extra: One-shot
AsyncTask
ExampleCaution: This shows another example of how to do the request. However, since
AsyncTask
is deprecated, it should be replaced by your App's thread scheduling, Kotlin Coroutines, Rx, ...不需要太复杂。最简单的框架方式是使用 ACCESS_NETWORK_STATE 权限并创建一个连接方法。
如果您有特定的主机和连接类型(wifi/移动),也可以使用 requestRouteToHost 。头脑。
您还需要:
在您的 Android 清单中。
No need to be complex. The simplest and framework manner is to use
ACCESS_NETWORK_STATE
permission and just make a connected methodYou can also use
requestRouteToHost
if you have a particualr host and connection type (wifi/mobile) in mind.You will also need:
in your android manifest.
要使
getActiveNetworkInfo()
正常工作,您需要将以下内容添加到清单中。To get
getActiveNetworkInfo()
to work you need to add the following to the manifest.看一下 ConnectivityManager 类。您可以使用此类来获取有关主机上活动连接的信息。 http://developer.android.com/reference/android/net/ConnectivityManager.html编辑
:您可以使用
或
解析返回的 NetworkInfo 对象的详细状态
枚举编辑编辑:要了解您是否可以访问主机,您可以使用
显然,我正在使用 Context.getSystemService(Context.CONNECTIVITY_SERVICE)作为代理说
Take a look at the ConnectivityManager class. You can use this class to get information on the active connections on a host. http://developer.android.com/reference/android/net/ConnectivityManager.html
EDIT: You can use
or
and parse the DetailedState enum of the returned NetworkInfo object
EDIT EDIT: To find out whether you can access a host, you can use
Obviously, I'm using Context.getSystemService(Context.CONNECTIVITY_SERVICE) as a proxy to say
检查此代码...它对我有用:)
然后,我定义处理程序:
...并启动测试:
check this code... it worked for me :)
Then, I define the handler:
...and launch the test:
在此链接 :
在您的清单文件中至少添加:
如果您正在访问它,您可能已经拥有 INTERNET 权限。那么允许测试连接性的布尔函数是:
Found at and modified (!) from this link :
In your manifest file add at least:
You probably already have the INTERNET permission if you are accessing it. Then a boolean function that allows to test for connectivity is:
我编写了这段代码,它是最简单的,它只是一个布尔值。
通过询问
if(isOnline()){
您可以获取是否存在连接以及是否可以连接到页面的状态代码
200
(稳定连接)。确保添加正确的
INTERNET
和ACCESS_NETWORK_STATE
权限。I made this code, it is the simplest and it is just a boolean.
by asking
if(isOnline()){
You get if there is a connection and if it can connect to a page the status code
200
(stable connection).Make sure to add the correct
INTERNET
andACCESS_NETWORK_STATE
permissions.它确实对我有用:
验证网络可用性:
验证互联网访问:
It does works for me:
To verify network availability:
To verify internet access:
有不止一种方法
首先,最短但效率低下的方法
只需要网络状态权限
然后这个方法,
如答案中所示
ConnectivityManager
是一个解决方案,我只是将它添加到一个方法中,这是一个所有使用的简化方法ConnectivityManager
如果有网络访问而不是互联网访问,则返回 true,这意味着如果您的 WiFi 连接到路由器但路由器没有互联网,它会返回 true,它会检查连接可用性其次,有效的方式
网络状态和需要互联网权限
然后这个类,
调用
CheckInternetAsyncTask
一些说明:-
你必须在
AsyncTask
上检查互联网,否则它会抛出android.os.NetworkOnMainThreadException
在某些情况下ConnectivityManager
用于检查网络访问情况,如果 true 发送请求(Ping)请求发送到
http://clients3.google.com/generate_204
,这个众所周知的 URL 会返回 HTTP 状态 204 的空页面,这比http:// 更快、更高效www.google.com
,阅读此< /a>.如果您有网站,最好将您的网站而不是 google,仅当您在应用程序内使用它时超时可以更改范围(20ms -> 2000ms),通常使用1500ms
There's more than one way
First, shortest but Inefficient way
Network State Permission only needed
Then this method,
As seen in answers
ConnectivityManager
is a solution, I just added it within a method this is a simplified method all useConnectivityManager
returns true if there is a network access not Internet access, means if your WiFi is connected to a router but the router has no internet it returns true, it check connection availabilitySecond, Efficient way
Network State and Internet Permissions needed
Then this class,
Call
CheckInternetAsyncTask
Some Explanations :-
you have to check Internet on
AsyncTask
, otherwise it can throwandroid.os.NetworkOnMainThreadException
in some casesConnectivityManager
used to check the network access if true sends request (Ping)Request send to
http://clients3.google.com/generate_204
, This well-known URL is known to return an empty page with an HTTP status 204 this is faster and more efficient thanhttp://www.google.com
, read this. if you have website it's preferred to put you website instead of google, only if you use it within the appTimeout can be changed range (20ms -> 2000ms), 1500ms is commonly used
Kotlin 和协程
我已将函数放置在
ViewModel
中,其中具有viewModelScope
。使用可观察的 LiveData,我向活动通知有关连接的信息。ViewModel
活动
Kotlin and coroutines
I have placed the function in a
ViewModel
, which has theviewModelScope
. Using an observableLiveData
I inform an activity about the connection.ViewModel
Activity
这是我使用的方法:
更好的是,检查以确保它已“连接”:
以下是如何使用该方法:
所需权限:
https://stackoverflow.com/a/16124915/950427
Here is the method I use:
Even better, check to make sure it is "connected":
Here is how to use the method:
Permission needed:
https://stackoverflow.com/a/16124915/950427
到目前为止我所见过的最短和最干净的方法应该是:
PS:这不会 ping 任何主机,它只是检查连接状态,因此如果您的路由器没有互联网连接并且您的设备已连接到它,则此方法将返回 确实,尽管您没有互联网。
对于实际测试,我建议执行 HttpHead 请求(例如到 www.google.com)并检查状态,如果其 200 OK 一切正常并且您的设备已互联网连接。
Of everything I have seen so far shortest and cleanest way should be:
PS: This does not ping any host, it just checks the connectionstatus, so if your router has no internet connection and your device is connected to it this method would return true although you have no internet.
For an actual test I would recommend execuding a HttpHead request (e.g. to www.google.com) and check the status, if its 200 OK everything is fine and your device has an internet connection.
移动设备上的一个重要用例是确保实际连接存在。当移动用户进入带有“强制门户”的 Wifi 网络并需要登录时,这是一个常见问题。我在后台使用此阻止功能来确保连接存在。
One important use case on mobile devices to it ensure an actual connection exists. This is a common problem when a mobile user enters a Wifi network with a "Captive Portal", in which they need to sign in. I use this blocking function in the background to ensure a connection exists.
这对我有用。尝试一下。
It's works for me. Try it out.
我使用此代码而不是 InetAddress :
Im using this code instead of the InetAddress :
您可以遍历所有网络连接并检查是否至少有一个可用连接:
You can iterate over all network connections and chek whether there is at least one available connection:
对我来说,检查 Activity 类中的连接状态不是一个好习惯,因为
应该在那里调用,或者您需要将 Activity 实例(上下文)下推到连接处理程序类才能检查那里的连接状态
当没有可用的连接(wifi、网络)时,我捕获 UnknownHostException 异常:
通过这种方式,我可以处理这种情况以及同一类中的其他情况(我的服务器总是用 json 字符串响应)
For me it was not a good practice to check the connection state in the Activity class, because
should be called there, or you need to push down your Activity instance (context) to the connection handler class to able to check the connection state there
When no available connection (wifi, network) I catch the UnknownHostException exception:
In this way I can handle this case along with the other cases in the same class (my server always response back with a json string)
最佳方法:
Best approach: