我有一个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();
}
}
检查Android网络/互联网连接状态并不复杂。 以下DetectConnection
类将帮助您检查此状态:
import android.content.Context;
import android.net.ConnectivityManager;
public class DetectConnection {
public static boolean checkInternetConnection(Context context) {
ConnectivityManager con_manager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (con_manager.getActiveNetworkInfo() != null
&& con_manager.getActiveNetworkInfo().isAvailable()
&& con_manager.getActiveNetworkInfo().isConnected()) {
return true;
} else {
return false;
}
}
}
有关更多详细信息,请访问如何检查Android网络/ Internet连接状态
我做了这个代码,它是最简单的,它只是一个布尔值。 通过询问if(isOnline()){
如果有连接,它可以连接到页面状态代码200
(稳定连接)。
确保添加正确的INTERNET
和ACCESS_NETWORK_STATE
权限。
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
try {
URL url = new URL("http://www.google.com");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(3000);
urlc.connect();
if (urlc.getResponseCode() == 200) {
return new Boolean(true);
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return false;
}
它对我有用。 试试看。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
URL url = new URL("http://stackoverflow.com/posts/11642475/edit" );
//URL url = new URL("http://www.nofoundwebsite.com/" );
executeReq(url);
Toast.makeText(getApplicationContext(), "Webpage is available!", Toast.LENGTH_SHORT).show();
}
catch(Exception e) {
Toast.makeText(getApplicationContext(), "oops! webpage is not available!", Toast.LENGTH_SHORT).show();
}
}
private void executeReq(URL urlObject) throws IOException
{
HttpURLConnection conn = null;
conn = (HttpURLConnection) urlObject.openConnection();
conn.setReadTimeout(30000);//milliseconds
conn.setConnectTimeout(3500);//milliseconds
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Start connect
conn.connect();
InputStream response =conn.getInputStream();
Log.d("Response:", response.toString());
}}
到目前为止,我所看到的最短和最干净的方式应该是:
public final static boolean isConnected( Context context )
{
final ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
PS:这不会ping任何主机,它只是检查connectionstatus,所以如果您的路由器没有互联网连接并且您的设备已连接到它,这种方法将返回true,尽管您没有互联网。
对于实际测试,我建议执行HttpHead请求(例如,到www.google.com)并检查状态,如果它的200 OK一切正常并且您的设备有互联网连接。
对我来说,检查Activity类中的连接状态不是一个好习惯,因为
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
应该在那里调用,或者你需要将你的Activity实例(上下文)下推到连接处理程序类,以便能够检查那里的连接状态当没有可用的连接(wifi,网络)时,我捕获了UnknownHostException异常:
JSONObject jObj = null;
Boolean responded = false;
HttpGet requestForTest = new HttpGet("http://myserver.com");
try {
new DefaultHttpClient().execute(requestForTest);
responded = true;
} catch (UnknownHostException e) {
jObj = new JSONObject();
try {
jObj.put("answer_code", 1);
jObj.put("answer_text", "No available connection");
} catch (Exception e1) {}
return jObj;
} catch (IOException e) {
e.printStackTrace();
}
通过这种方式,我可以处理这种情况以及同一类中的其他情况(我的服务器总是以json字符串回复)
最佳方法:
public static boolean isOnline() {
try {
InetAddress.getByName("google.com").isReachable(3);
return true;
} catch (UnknownHostException e){
return false;
} catch (IOException e){
return false;
}
}
看一下ConnectivityManager类。 您可以使用此类来获取有关主机上活动连接的信息。 http://developer.android.com/reference/android/net/ConnectivityManager.html
编辑:你可以使用
Context.getSystemService(Context.CONNECTIVITY_SERVICE)
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
要么
Context.getSystemService(Context.CONNECTIVITY_SERVICE)
.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
并解析返回的NetworkInfo对象的DetailedState枚举
编辑编辑:要了解您是否可以访问主机,您可以使用
Context.getSystemService(Context.CONNECTIVITY_SERVICE)
.requestRouteToHost(TYPE_WIFI, int hostAddress)
显然,我使用Context.getSystemService(Context.CONNECTIVITY_SERVICE)作为代理来说
ConnectivityManager cm = Context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.yourMethodCallHere();
我使用此代码而不是InetAddress:
try {
URL url = new URL("http://"+params[0]);
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setRequestProperty("User-Agent", "Android Application:"+Z.APP_VERSION);
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(1000 * 30); // mTimeout is in seconds
urlc.connect();
if (urlc.getResponseCode() == 200) {
Main.Log("getResponseCode == 200");
return new Boolean(true);
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
以下是我的Utils
类的代码:
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager
= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
移动设备上的一个重要用例是确保存在实际连接。 当移动用户进入具有“强制门户”的Wifi网络时,这是一个常见问题,他们需要登录。我在后台使用此阻止功能以确保存在连接。
/*
* Not Thread safe. Blocking thread. Returns true if it
* can connect to URL, false and exception is logged.
*/
public boolean checkConnectionHttps(String url){
boolean responded = false;
HttpGet requestTest = new HttpGet(url);
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);
HttpConnectionParams.setSoTimeout(params, 5000);
DefaultHttpClient client = new DefaultHttpClient(params);
try {
client.execute(requestTest);
responded = true;
} catch (ClientProtocolException e) {
Log.w(MainActivity.TAG,"Unable to connect to " + url + " " + e.toString());
} catch (IOException e) {
Log.w(MainActivity.TAG,"Unable to connect to " + url + " " + e.toString());
e.printStackTrace();
}
return responded;
}
这是我使用的方法:
public boolean isNetworkAvailable(final Context context) {
return ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo() != null;
}
更好的是,检查以确保它“连接”:
public boolean isNetworkAvailable(final Context context) {
final ConnectivityManager connectivityManager = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected();
}
以下是如何使用该方法:
if (isNetworkAvailable(context)) {
// code here
} else {
// code
}
需要许可:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
https://stackoverflow.com/a/16124915/950427
public class Network {
Context context;
public Network(Context context){
this.context = context;
}
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
}
}
不需要复杂。 最简单的框架方式是使用ACCESS_NETWORK_STATE
权限并只创建一个连接的方法
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null &&
cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
如果您有特定的主机和连接类型(wifi /移动),您也可以使用requestRouteToHost
。
您还需要:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
在你的Android清单中。
更新29/06/2015如果您正在使用Xamarin.Android并想要检查连接性,则可以使用Nuget包在多个平台上为您提供此功能。 好的候选人在这里和这里 。 [更新完]
上面的答案非常好,但它们都是Java,几乎所有的都检查连接。 就我而言,我需要与特定类型的连接建立连接,而我正在开发Xamarin.Android。 而且,我没有在硬件层传递对我的活动Context的引用,我使用了Application Context。 所以这是我的解决方案,以防有人来这里有类似的要求。 我还没有完成全部测试,一旦完成测试就会更新答案
using Android.App;
using Android.Content;
using Android.Net;
namespace Leopard.Mobile.Hal.Android
{
public class AndroidNetworkHelper
{
public static AndroidNetworkStatus GetWifiConnectivityStatus()
{
return GetConnectivityStatus(ConnectivityType.Wifi);
}
public static AndroidNetworkStatus GetMobileConnectivityStatus()
{
return GetConnectivityStatus(ConnectivityType.Mobile);
}
#region Implementation
private static AndroidNetworkStatus GetConnectivityStatus(ConnectivityType connectivityType)
{
var connectivityManager = (ConnectivityManager)Application.Context.GetSystemService(Context.ConnectivityService);
var wifiNetworkInfo = connectivityManager.GetNetworkInfo(connectivityType);
var result = GetNetworkStatus(wifiNetworkInfo);
return result;
}
private static AndroidNetworkStatus GetNetworkStatus(NetworkInfo wifiNetworkInfo)
{
var result = AndroidNetworkStatus.Unknown;
if (wifiNetworkInfo != null)
{
if (wifiNetworkInfo.IsAvailable && wifiNetworkInfo.IsConnected)
{
result = AndroidNetworkStatus.Connected;
}
else
{
result = AndroidNetworkStatus.Disconnected;
}
}
return result;
}
#endregion
}
public enum AndroidNetworkStatus
{
Connected,
Disconnected,
Unknown
}
使用ConnectivityManager的其他答案是错误的,因为拥有网络连接并不意味着您可以访问Internet。 例如,用户可能连接到咖啡店的WiFi门户但无法访问互联网。 要检查互联网是否可访问,您必须尝试连接到实际的服务器。 通常,当您要执行此操作时,您需要记住要连接的特定服务器,因此请检查您是否可以连接到该服务器。 这是检查服务器连接的简单方法。
private boolean isOnTheInternet() {
try {
URLConnection urlConnection = new URL("http://yourserver").openConnection();
urlConnection.setConnectTimeout(400);
urlConnection.connect();
return true;
} catch (Exception e) {
return false;
}
}
设置ConnectTimeout的原因是,否则它默认为TCP超时,可以持续很长时间。
另请注意,Android不允许您在主线程上运行此操作。
此方法为您提供了一种非常快速的方法(用于实时反馈)或更慢的方法(用于需要可靠性的一次性检查)的选项
public boolean isNetworkAvailable(bool SlowButMoreReliable) {
bool Result = false;
try {
if(SlowButMoreReliable){
ConnectivityManager MyConnectivityManager = null;
MyConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo MyNetworkInfo = null;
MyNetworkInfo = MyConnectivityManager.getActiveNetworkInfo();
Result = MyNetworkInfo != null && MyNetworkInfo.isConnected();
} else
{
Runtime runtime = Runtime.getRuntime();
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int i = ipProcess.waitFor();
Result = i== 0;
}
} catch(Exception ex)
{
//Common.Exception(ex); //This method is one you should have that displays exceptions in your log
}
return Result;
}
它对我有用:
要验证网络可用性:
private Boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();}
验证互联网访问:
public Boolean isOnline() {
try {
Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
return reachable;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
只需创建以下检查Internet连接的类:
public class ConnectionStatus {
private Context _context;
public ConnectionStatus(Context context) {
this._context = context;
}
public boolean isConnectionAvailable() {
ConnectivityManager connectivity = (ConnectivityManager) _context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
return false;
}
}
该类只包含一个返回连接状态的布尔值的方法。 因此,简单来说,如果方法找到与Internet的有效连接,则返回值为true
,否则为false
如果未找到有效连接。
然后,MainActivity中的以下方法从前面描述的方法调用结果,并提示用户采取相应的操作:
public void addListenerOnWifiButton() {
Button btnWifi = (Button)findViewById(R.id.btnWifi);
iia = new ConnectionStatus(getApplicationContext());
isConnected = iia.isConnectionAvailable();
if (!isConnected) {
btnWifi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
Toast.makeText(getBaseContext(), "Please connect to a hotspot",
Toast.LENGTH_SHORT).show();
}
});
}
else {
btnWifi.setVisibility(4);
warning.setText("This app may use your mobile data to update events and get their details.");
}
}
在上面的代码中,如果结果为false,(因此没有互联网连接,用户将被带到Android wi-fi面板,在那里他被提示连接到Wi-Fi热点。
isConnectedOrConnecting()
(在大多数答案中使用)检查任何网络连接 // ICMP
public boolean isOnline() {
Runtime runtime = Runtime.getRuntime();
try {
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = ipProcess.waitFor();
return (exitValue == 0);
}
catch (IOException e) { e.printStackTrace(); }
catch (InterruptedException e) { e.printStackTrace(); }
return false;
}
+
可以在主线程上运行
-
不适用于某些旧设备(Galays S3等),如果没有可用的互联网,它会阻塞一段时间。
// TCP/HTTP/DNS (depending on the port, 53=DNS, 80=HTTP, etc.)
public boolean isOnline() {
try {
int timeoutMs = 1500;
Socket sock = new Socket();
SocketAddress sockaddr = new InetSocketAddress("8.8.8.8", 53);
sock.connect(sockaddr, timeoutMs);
sock.close();
return true;
} catch (IOException e) { return false; }
}
+
非常快(无论哪种方式),适用于所有设备, 非常可靠
-
无法在UI线程上运行
这在每台设备上都非常可靠,而且速度非常快。 它需要在单独的任务中运行(例如ScheduledExecutorService
或AsyncTask
)。
真的够快吗?
是的,非常快;-)
没有可靠的方法来检查互联网,除了在互联网上测试一些东西?
不是我所知,但请告诉我,我会编辑我的答案。
如果DNS关闭怎么办?
Google DNS(例如8.8.8.8
)是世界上最大的公共DNS。 截至2013年,它每天为1300亿个请求提供服务。 我们只是说,你的应用可能不是当天的话题。
需要哪些权限?
<uses-permission android:name="android.permission.INTERNET" />
只是互联网访问 - 惊喜^^(顺便说一句,你有没有想过,如果没有这个许可,这里建议的一些方法甚至可能有一个关于互联网访问的远程胶水?)
AsyncTask
示例 class InternetCheck extends AsyncTask<Void,Void,Boolean> {
private Consumer mConsumer;
public interface Consumer { void accept(Boolean internet); }
public InternetCheck(Consumer consumer) { mConsumer = consumer; execute(); }
@Override protected Boolean doInBackground(Void... voids) { try {
Socket sock = new Socket();
sock.connect(new InetSocketAddress("8.8.8.8", 53), 1500);
sock.close();
return true;
} catch (IOException e) { return false; } }
@Override protected void onPostExecute(Boolean internet) { mConsumer.accept(internet); }
}
///
// Usage
new InternetCheck(internet -> { /* do something with boolean response */ });
RxJava/RxAndroid
示例(Kotlin) fun hasInternetConnection(): Single<Boolean> {
return Single.fromCallable {
try {
// Connect to Google DNS to check for connection
val timeoutMs = 1500
val socket = Socket()
val socketAddress = InetSocketAddress("8.8.8.8", 53)
socket.connect(socketAddress, timeoutMs)
socket.close()
true
} catch (e: IOException) {
false
}
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
///
// Usage
hasInternetConnection().subscribe { hasInternet -> /* do something */}
您可以使用此方法检测网络可用性 -
public static boolean isDeviceOnline(Context context) {
boolean isConnectionAvail = false;
try {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo.isConnected();
} catch (Exception e) {
e.printStackTrace();
}
return isConnectionAvail;
}
这包含在android docs http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html中
要使getActiveNetworkInfo()
,您需要将以下内容添加到清单中。
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
我已经完成了所有的答案,我想出了自己的答案,首先检查互联网是否可用,如果互联网可用,那么它会检查它是否有效。
我已经包含了所有必要的方法和类来检查活动的Internet连接。
NetworkUtils.class
public class NetworkUtils {
public static final int STATUS_CONNECTED = 0 ;
public static boolean isInternetAvailable(Context ctx){
ConnectivityManager cm = (ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}
public static int isInternetActiveWithPing() {
try {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = process.waitFor();
return exitValue;
} catch (Exception ex) {
return -1;
}
}
public static boolean isInternetActiveWithInetAddress() {
try {
InetAddress inetAddress = InetAddress.getByName("www.google.com");
return inetAddress != null && !inetAddress.toString().equals("");
} catch (Exception ex) {
return false;
}
}
public static void displayInternetConnectionMessage(Context ctx){
Toast.makeText(ctx, "Check Internet Connection", Toast.LENGTH_SHORT).show();
}
}
您可以使用以下代码检查Internet是否处于活动状态:
private void checkInternetConnection() {
if (NetworkUtils.isInternetAvailable(this)) {
new Thread(new Runnable() {
@Override
public void run() {
if (NetworkUtils.isInternetActiveWithPing() == NetworkUtils.STATUS_CONNECTED) {
performNetworkingOperations();
} else {
if (NetworkUtils.isInternetActiveWithInetAddress()) {
performNetworkingOperations();
} else {
displayConnectionMessage();
}
}
}
}).start();
} else {
displayConnectionMessage();
}
}
private void performNetworkingOperations() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "Internet is Available", Toast.LENGTH_SHORT).show();
}
});
}
private void displayConnectionMessage() {
runOnUiThread(new Runnable() {
@Override
public void run() {
NetworkUtils.displayInternetConnectionMessage(MainActivity.this);
}
});
}
如果设备处于飞行模式(或者可能是在没有可用网络的其他情况下), cm.getActiveNetworkInfo()
将为null
,因此您需要添加null
检查。
修改过( Eddie的解决方案 )如下:
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
还要将以下权限添加到AndroidManifest.xml
:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
另一个小问题,如果您在给定时间点绝对需要网络连接,那么最好使用netInfo.isConnected()
而不是netInfo.isConnectedOrConnecting
。 我想这取决于个人用例。
检查我们是否与isAvailable()连接以及是否可以与isConnected()建立连接非常重要
private static ConnectivityManager manager;
public static boolean isOnline(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected();
}
并且您可以确定网络活动WiFi的类型:
public static boolean isConnectedWifi(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI;
}
或移动Móvil :
public static boolean isConnectedMobile(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE;
}
不要忘记权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
我已经应用了@Levit提供的解决方案并创建了不会调用额外Http请求的函数。
它将解决Unable to Resolve Host
的错误
public static boolean isInternetAvailable(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork == null) return false;
switch (activeNetwork.getType()) {
case ConnectivityManager.TYPE_WIFI:
if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
isInternet())
return true;
break;
case ConnectivityManager.TYPE_MOBILE:
if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
isInternet())
return true;
break;
default:
return false;
}
return false;
}
private static boolean isInternet() {
Runtime runtime = Runtime.getRuntime();
try {
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = ipProcess.waitFor();
Debug.i(exitValue + "");
return (exitValue == 0);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return false;
}
现在称之为,
if (!isInternetAvailable(getActivity())) {
//Show message
} else {
//Perfoem the api request
}
在此链接中找到并修改(!):
在您的清单文件中至少添加:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
如果您正在访问它,您可能已经拥有INTERNET权限。 然后,允许测试连接的布尔函数是:
private boolean checkInternetConnection() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
// test for connection
if (cm.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().isAvailable()
&& cm.getActiveNetworkInfo().isConnected()) {
return true;
} else {
Log.v(TAG, "Internet Connection Not Present");
return false;
}
}
这不止一种方式
首先,最短但效率低的方式
仅需要网络状态权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
那么这个方法,
public boolean activeNetwork () {
ConnectivityManager cm =
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnected();
return isConnected;
}
如答案中所见, ConnectivityManager
是一个解决方案,我只是在一个方法中添加它,这是一个所有使用的简化方法
如果网络访问不是Internet访问,则ConnectivityManager
返回true,表示如果您的WiFi连接到路由器但路由器没有互联网,则返回true,它会检查连接可用性
第二,有效的方式
需要网络状态和Internet权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
然后这节课,
public class CheckInternetAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private Context context;
public CheckInternetAsyncTask(Context context) {
this.context = context;
}
@Override
protected Boolean doInBackground(Void... params) {
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnected();
if (isConnected) {
try {
HttpURLConnection urlc = (HttpURLConnection)
(new URL("http://clients3.google.com/generate_204")
.openConnection());
urlc.setRequestProperty("User-Agent", "Android");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(1500);
urlc.connect();
if (urlc.getResponseCode() == 204 &&
urlc.getContentLength() == 0)
return true;
} catch (IOException e) {
Log.e("TAG", "Error checking internet connection", e);
return false;
}
} else {
Log.d("TAG", "No network available!");
return false;
}
return null;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
Log.d("TAG", "result" + result);
if(result){
// do ur code
}
}
}
调用CheckInternetAsyncTask
new CheckInternetAsyncTask(getApplicationContext()).execute();
一些解释: -
你必须在AsyncTask
上检查Internet,否则它会在某些情况下抛出android.os.NetworkOnMainThreadException
如果true发送请求,则ConnectivityManager
用于检查网络访问(Ping)
请求发送到http://clients3.google.com/generate_204
,已知这个众所周知的网址会返回一个HTTP状态为204的空白页面,这比http://www.google.com
更快,更有效率,阅读这个 。 如果你有网站,只有你在应用程序中使用它,首选你的网站而不是谷歌
超时可以改变范围(20ms - > 2000ms),常用1500ms
检查这段代码......它对我有用:)
public static void isNetworkAvailable(final Handler handler, final int timeout) {
// ask fo message '0' (not connected) or '1' (connected) on 'handler'
// the answer must be send before before within the 'timeout' (in milliseconds)
new Thread() {
private boolean responded = false;
@Override
public void run() {
// set 'responded' to TRUE if is able to connect with google mobile (responds fast)
new Thread() {
@Override
public void run() {
HttpGet requestForTest = new HttpGet("http://m.google.com");
try {
new DefaultHttpClient().execute(requestForTest); // can last...
responded = true;
}
catch (Exception e) {
}
}
}.start();
try {
int waited = 0;
while(!responded && (waited < timeout)) {
sleep(100);
if(!responded ) {
waited += 100;
}
}
}
catch(InterruptedException e) {} // do nothing
finally {
if (!responded) { handler.sendEmptyMessage(0); }
else { handler.sendEmptyMessage(1); }
}
}
}.start();
}
然后,我定义处理程序:
Handler h = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what != 1) { // code if not connected
} else { // code if connected
}
}
};
...并启动测试:
isNetworkAvailable(h,2000); // get the answser within 2000 ms
您可以遍历所有网络连接并判断是否至少有一个可用连接:
public boolean isConnected() {
boolean connected = false;
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm != null) {
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if ((ni.getTypeName().equalsIgnoreCase("WIFI")
|| ni.getTypeName().equalsIgnoreCase("MOBILE"))
&& ni.isConnected() && ni.isAvailable()) {
connected = true;
}
}
}
return connected;
}