简体   繁体   English

如何以编程方式检查 Android 中互联网连接的可用性?

[英]How to programmatically check availibilty of internet connection in Android?

I want to check programmatically whether there is an internet connection in Android phone/emulator.我想以编程方式检查 Android 手机/模拟器中是否有互联网连接。 So that once I am sure that an internet connection is present then I'll make a call to the internet.因此,一旦我确定存在互联网连接,我就会拨打互联网电话。

So its like "Hey emulator! If you have an internet connection, then please open this page, else doSomeThingElse();"所以它就像“嘿模拟器!如果你有互联网连接,那么请打开这个页面,否则 doSomeThingElse();”

The method I implemented for myself:我为自己实现的方法:

/*
 * isOnline - Check if there is a NetworkConnection
 * @return boolean
 */
protected boolean isOnline() {
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnected()) {
        return true;
    } else {
        return false;
    }
}

Be aware of that this is a NetworkConnection-Check.请注意,这是网络连接检查。 If there is a NetworkConnection it doesn't have to be a InternetConnection.如果存在 NetworkConnection,则它不必是 InternetConnection。

Being connected to a network does not guarantee internet connectivity.连接到网络并不能保证互联网连接。

You might be connected to your home's wifi, but you might not have internet connection.您可能已连接到您家的 wifi,但您可能没有互联网连接。 Or, you might be in a restaurant, where you can be connected to the wifi, but still need password for the hotspot in order to use the internet.或者,您可能在一家餐厅,在那里您可以连接到 wifi,但仍需要热点密码才能使用互联网。 In such cases the above methods will return true, yet the device wont have internet, and if not surrounded with the right try and catches, the app might crash.在这种情况下,上述方法将返回 true,但设备不会联网,如果没有正确的尝试和捕获,应用程序可能会崩溃。

Bottom line, network connectivity, does not mean internet connectivity, it merely means that your device's wireless hardware can connect to another host and both can make a connection.最重要的是,网络连接并不意味着互联网连接,它只是意味着您设备的无线硬件可以连接到另一台主机,并且两者都可以建立连接。

Below is a method that can check if the device can connect to a website and returns an answer accordingly.下面是一种可以检查设备是否可以连接到网站并相应地返回答案的方法。

if (networkConnectivity())
{
    try
    {
        HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.anywebsiteyouthinkwillnotbedown.com").openConnection());
        urlc.setRequestProperty("User-Agent", "Test");
        urlc.setRequestProperty("Connection", "close");
        urlc.setConnectTimeout(3000); //choose your own timeframe
        urlc.setReadTimeout(4000); //choose your own timeframe
        urlc.connect();
        networkcode2 = urlc.getResponseCode();
        return (urlc.getResponseCode() == 200);
    } catch (IOException e)
    {
        return (false);  //connectivity exists, but no internet.
    }
} else
{
    return false;  //no connectivity
}

as for the question title , you want to check the internet access ,至于问题标题,你想检查互联网访问,

so the fastest way and it is efficient at least for now ,所以最快的方式,至少目前是有效的,

thnx to levit based on his answer https://stackoverflow.com/a/27312494/3818437 thnx to levit基于他的回答https://stackoverflow.com/a/27312494/3818437

If you just want to check for a connection to any network - not caring if internet is available - then most of the answers here (including the accepted), implementing isConnectedOrConnecting() will work well.如果您只想检查与任何网络的连接 - 不关心互联网是否可用 - 那么这里的大多数答案(包括已接受的),实现 isConnectedOrConnecting() 将工作得很好。 If you want to know if you have an internet connection (as the question title indicates) please read on Ping for the main name servers如果您想知道您是否有互联网连接(如问题标题所示),请阅读 Ping 以了解主要名称服务器

 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; }

That's it!就是这样! Yes that short, yes it is fast, no it does not need to run in background, no you don't need root privileges.是的,很短,是的,它很快,不需要在后台运行,不需要 root 权限。

Possible Questions可能的问题

Is this really fast enough?这真的够快了吗?

Yes, very fast!是的,非常快!

Is there really no reliable way to check if internet is available, other than testing something on the internet?除了在互联网上测试某些东西之外,真的没有可靠的方法来检查互联网是否可用吗?

Not as far as I know, but let me know, and I will edit my answer.据我所知,但让我知道,我会编辑我的答案。

Couldn't I just ping my own page, which I want to request anyways?我不能只是 ping 我自己想要请求的页面吗?

Sure!当然! You could even check both, if you want to differentiate between "internet connection available" and your own servers beeing reachable如果您想区分“互联网连接可用”和您自己的服务器可访问,您甚至可以同时检查两者

What if the DNS is down?如果 DNS 关闭怎么办?

Google DNS (eg 8.8.8.8) is the largest public DNS service in the world. Google DNS(例如 8.8.8.8)是世界上最大的公共 DNS 服务。 As of 2013 it serves 130 billion requests a day.截至 2013 年,它每天处理 1300 亿个请求。 Let 's just say, your app not responding would probably not be the talk of the day.只是说,您的应用程序没有响应可能不是今天的话题。

Which permissions are required?需要哪些权限?

Just internet access - what surprise ^^ (Btw have you ever thought about, how some of the methods suggested here could even have a remote glue about the availablility of internet, without this permission?)只是互联网访问 - 什么惊喜^^(顺便说一句,你有没有想过,这里建议的一些方法甚至可以在没有这个许可的情况下远程连接互联网的可用性?)

i have been using these two methods to check internet status sometimes https protocol doesn't work try http protocol我一直在使用这两种方法来检查互联网状态有时https协议不起作用尝试http协议

// Check if network is available
public static boolean isNetworkAvailable() {
    ConnectivityManager cm = (ConnectivityManager)
            AppGlobals.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = cm.getActiveNetworkInfo();
    return networkInfo != null && networkInfo.isConnected();
}

// ping the google server to check if internet is really working or not
public static boolean isInternetWorking() {
    boolean success = false;
    try {
        URL url = new URL("https://google.com");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setConnectTimeout(10000);
        connection.connect();
        success = connection.getResponseCode() == 200;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return success;
}

if http does not work its because of the new android security they donot allow plain text communication now.如果 http 由于新的 android 安全性而不起作用,他们现在不允许纯文本通信。 for now just to by pass it.现在只是绕过它。

android:usesCleartextTraffic="true"机器人:使用CleartextTraffic =“真”

Try this:试试这个:

ConnectivityManager connec = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);

if(connec.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED || connec.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTING  ) {
   text.setText("hey your online!!!")     ;               
   //Do something in here when we are connected   
} else if(connec.getNetworkInfo(0).getState() == NetworkInfo.State.DISCONNECTED ||  connec.getNetworkInfo(1).getState() == NetworkInfo.State.DISCONNECTED   ) {
   text.setText("Look your not online");           
}

From my OLD Answer here从我的旧答案这里

Just try this试试这个

I have applied the solution provided by @Levit and created function that will not call the extra Http Request.我已经应用了@Levit 提供的解决方案,并创建了不会调用额外 Http 请求的函数。

It will solve the error Unable to Resolve Host它将解决错误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;
}

Now call it like,现在称之为,

if (!isInternetAvailable(getActivity())) {
     //Show message
} else {
     //Perfoem the api request
}

Because you are connected to a network does not guaruntee that you have internet, I have gone to just making my calls to the internet inside of a try catch block.因为您连接到网络并不能保证您有互联网,所以我只是在 try catch 块内拨打互联网电话。 Then catch the UnknownHostException to handle no internet.然后捕获 UnknownHostException 以处理没有互联网。

this code must be run in background thread此代码必须在后台线程中运行

fun hasActiveInternetConnection(): Boolean {
    return try {
        val ipAddr: InetAddress = InetAddress.getByName("google.com")
        !ipAddr.equals("")
    } catch (e: java.lang.Exception) {
        false
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM