Detectar se o dispositivo Android tem conexão com a Internet


138

Preciso dizer se meu dispositivo tem conexão com a Internet ou não. Encontrei muitas respostas como:

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager 
         = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null;
}

(Retirado de Detectar se há uma conexão com a Internet disponível no Android .)

Mas isso não está certo, por exemplo, se eu estiver conectado a uma rede sem fio que não tem acesso à Internet , esse método retornará verdadeiro ... Existe uma maneira de saber se o dispositivo tem conexão com a Internet e não se está apenas conectado para algo?


Ei, você pode ir com [isso] [1] também. Isso pode ajudar! [1]: stackoverflow.com/questions/4238921/…
akshay


O isNetworkConnectedbloco de funções contém código descontinuado para todos Build.VERSION.SDK_INT >= Build.VERSION_CODES.M. Uma discussão mais aprofundada sobre o assunto e como corrigi-lo pode ser encontrada aqui stackoverflow.com/questions/53532406/…
Basti Vagabond

Respostas:


182

Você está certo. O código que você forneceu apenas verifica se há uma conexão de rede. A melhor maneira de verificar se há uma conexão ativa com a Internet é tentar conectar-se a um servidor conhecido via http.

public static boolean hasActiveInternetConnection(Context context) {
    if (isNetworkAvailable(context)) {
        try {
            HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection());
            urlc.setRequestProperty("User-Agent", "Test");
            urlc.setRequestProperty("Connection", "close");
            urlc.setConnectTimeout(1500); 
            urlc.connect();
            return (urlc.getResponseCode() == 200);
        } catch (IOException e) {
            Log.e(LOG_TAG, "Error checking internet connection", e);
        }
    } else {
        Log.d(LOG_TAG, "No network available!");
    }
    return false;
}

É claro que você pode substituir a http://www.google.comURL por qualquer outro servidor ao qual você deseja se conectar ou por um servidor que você conheça com um bom tempo de atividade.

Como Tony Cho também apontou neste comentário abaixo , certifique-se de não executar esse código no thread principal, caso contrário, você receberá uma exceção NetworkOnMainThread (no Android 3.0 ou posterior). Use um AsyncTask ou Runnable.

Se você deseja usar o google.com, consulte a modificação de Jeshurun. Em sua resposta, ele modificou meu código e o tornou um pouco mais eficiente. Se você se conectar a

HttpURLConnection urlc = (HttpURLConnection) 
            (new URL("http://clients3.google.com/generate_204")
            .openConnection());

e verifique o código de resposta para 204

return (urlc.getResponseCode() == 204 && urlc.getContentLength() == 0);

então você não precisa buscar a página inicial do Google inteira primeiro.


9
@varunbhardwaj, você pode simplesmente acessar um site diferente (por exemplo, baidu.com ao implantar seu aplicativo na China) ou pode tentar um segundo site se o primeiro falhar para garantir que não haja conexão.
THelper

2
Marquei sua resposta com +1 e sei usá-la no meu aplicativo, mas há um grande caso de dependência em algum site e minha pergunta ainda permanece sem resposta. de qualquer maneira ótima solução alternativa thanx.
varun bhardwaj

2
@blackcrow Depende de quanto tempo você / os usuários estão dispostos a esperar. Pessoalmente, considero 1000ms o limite inferior, 6000ms sobre a média e 15000ms. Mas se a verificação estiver sendo executada em segundo plano e o usuário não estiver esperando, você poderá usar tempos limite muito mais longos.
THelper

1
@varunbhardwaj Deve haver algum URI que você possa acessar em seus serviços da web. A primeira coisa que solicitamos quando o aplicativo é iniciado é um arquivo de inicialização que contém várias informações de configuração, que permitem alterar vários parâmetros do lado do servidor. Algo assim pode ser usado.
21412 Steve Steve

11
Isso também deve estar em um encadeamento em segundo plano (enquanto a verificação do ConnectivityManagernão exige isso). Caso contrário, nos dispositivos Android 4.x +, você receberá uma NetworkOnMainThreadexceção.
Anthony Chuinard

90

Modifiquei ligeiramente a resposta do THelper para usar um hack conhecido que o Android já usa para verificar se a rede Wi-Fi conectada tem acesso à Internet. Isso é muito mais eficiente do que acessar a página inicial do Google inteira. Veja aqui e aqui para mais informações.

public static boolean hasInternetAccess(Context context) {
    if (isNetworkAvailable(context)) {
        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();
            return (urlc.getResponseCode() == 204 &&
                        urlc.getContentLength() == 0);
        } catch (IOException e) {
            Log.e(TAG, "Error checking internet connection", e);
        }
    } else {
        Log.d(TAG, "No network available!");
    }
    return false;
}

1
Olá, está tudo bem em usar essa prática nos aplicativos atuais?
Slava Fomin II

Isso é eficiente na implementação em nosso aplicativo atual?
therealprashant

5
Seria muito mais eficiente que o método na resposta acima. Agarrar a página inicial do Google é muito ineficiente, especialmente se eles tiverem um doodle.
precisa

1
A resposta marcada como correta deve ser atualizada com isso, pois melhora a resposta. Bem homem feito, graças
Hugo

3
Você pode querer usar g.cn/generate_204 vez de clients3.google.com/generate_204 se você quiser testar a conectividade na China, bem
breez

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

return true se a internet estiver realmente disponível

Verifique se você tem essas duas permissões

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

se o http não funcionar, é por causa da nova segurança do Android que eles não permitem a comunicação de texto sem formatação agora. por enquanto apenas para passar por isso.

android: usesCleartextTraffic = "true"


Esta é a melhor e mais completa resposta: é a maneira mais curta de fazer as coisas (um ping não acessa todo o site), executa independentemente de qual conexão você possui e executa no processo conquistado, para que ele se divirta com as versões do Android .
MacD

o que você quer dizer ? Aqui está outro trecho que eu estou usando em um projeto atual checkInternet
Bilal Shahid

o que ele quis dizer é que essa chamada bloqueará a interface do usuário e ele precisará fazer essa chamada em thread?
Amit Hooda

2
Isso não funciona para mim ... Causado por: android.os.NetworkOnMainThreadException em android.os.StrictMode $ AndroidBlockGuardPolicy.onNetwork (StrictMode.java:1273) em java.net.InetAddress.lookupHostByName (InetAddress.java:431) at
Maryadi Poipo 30/06

@HyosokaPoipo você não deve invocar isso no thread principal. Use um segmento separado ou AsyncTask.
Pramesh Bajracharya

14

Se você estiver segmentando Lollipop ou superior, é possível usar a nova classe NetworkCapabilities, ou seja:

public static boolean hasInternetConnection(final Context context) {
    final ConnectivityManager connectivityManager = (ConnectivityManager)context.
            getSystemService(Context.CONNECTIVITY_SERVICE);

    final Network network = connectivityManager.getActiveNetwork();
    final NetworkCapabilities capabilities = connectivityManager
            .getNetworkCapabilities(network);

    return capabilities != null
            && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}

1
connectivityManager.getActiveNetwork();requer a API lvl23, que é Marshmallow e não Lollipop.
Saenic

Também devemos verificar os recursos.hasCapability (NetworkCapabilities.NET_CAPABILITY_INTERNET)?
Alex #

Alex capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)parecia fazer o truque para mim!
Rstojano 29/05/19

6

Você não precisa necessariamente fazer uma conexão HTTP completa. Você pode tentar abrir uma conexão TCP com um host conhecido e, se for bem-sucedido, você possui conectividade com a Internet.

public boolean hostAvailable(String host, int port) {
  try (Socket socket = new Socket()) {
    socket.connect(new InetSocketAddress(host, port), 2000);
    return true;
  } catch (IOException e) {
    // Either we have a timeout or unreachable host or failed DNS lookup
    System.out.println(e);
    return false;
  }
}

Em seguida, basta verificar com:

boolean online = hostAvailable("www.google.com", 80);

a porta 80 é uma porta segura para usar?
Ralphgabb 06/10

Enquanto estiver hospedando um servidor HTTP, ele deverá aceitar uma conexão TCP na porta 80.
Xiv 8/16

Isso deve ser usado dentro de um AsyncTask ou apenas chamado no método onCreate do MainActivity, por exemplo?
AlexioVay

@ Qualquer coisa relacionada à rede não deve ser executada no thread principal / interface do usuário. Então, sim, isso deve ser usado dentro de umAsyncTask
winklerrr

6

Com base nas respostas aceitas, construí esta classe com um ouvinte para que você possa usá-la no thread principal:

Primeiro : a classe InterntCheck que verifica a conexão com a Internet em segundo plano e depois chama um método de ouvinte com o resultado.

public class InternetCheck extends AsyncTask<Void, Void, Void> {


    private Activity activity;
    private InternetCheckListener listener;

    public InternetCheck(Activity x){

        activity= x;

    }

    @Override
    protected Void doInBackground(Void... params) {


        boolean b = hasInternetAccess();
        listener.onComplete(b);

        return null;
    }


    public void isInternetConnectionAvailable(InternetCheckListener x){
        listener=x;
        execute();
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager) activity.getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null;
    }
    private boolean hasInternetAccess() {
        if (isNetworkAvailable()) {
            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();
                return (urlc.getResponseCode() == 204 &&
                        urlc.getContentLength() == 0);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            Log.d("TAG", "No network available!");
        }
        return false;
    }

    public interface InternetCheckListener{
        void onComplete(boolean connected);
    }

}

Segundo : instancie uma instância da classe no thread principal e aguarde a resposta (se você trabalhou com a API do Firebase para android antes que isso lhe seja familiar!).

new InternetCheck(activity).isInternetConnectionAvailable(new InternetCheck.InternetCheckListener() {

        @Override
        public void onComplete(boolean connected) {
           //proceed!
        }
    });

Agora, no método onComplete, você saberá se o dispositivo está conectado à Internet ou não.


3

tente este

public class ConnectionDetector {
    private Context _context;

    public ConnectionDetector(Context context) {
        this._context = context;
    }

    public boolean isConnectingToInternet() {
        if (networkConnectivity()) {
            try {
                HttpURLConnection urlc = (HttpURLConnection) (new URL(
                        "http://www.google.com").openConnection());
                urlc.setRequestProperty("User-Agent", "Test");
                urlc.setRequestProperty("Connection", "close");
                urlc.setConnectTimeout(3000);
                urlc.setReadTimeout(4000);
                urlc.connect();
                // networkcode2 = urlc.getResponseCode();
                return (urlc.getResponseCode() == 200);
            } catch (IOException e) {
                return (false);
            }
        } else
            return false;

    }

    private boolean networkConnectivity() {
        ConnectivityManager cm = (ConnectivityManager) _context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            return true;
        }
        return false;
    }
}

você precisará adicionar a seguinte permissão ao seu arquivo de manifesto:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

Então chame assim:

if((new ConnectionDetector(MyService.this)).isConnectingToInternet()){
    Log.d("internet status","Internet Access");
}else{
    Log.d("internet status","no Internet Access");
}


este gay usa try catch, portanto, o erro não é mostrado. Primeiro, adicione permissão à internet e tente isso. seu trabalho está bem #
23416 Attaullah

Deixe-me dizer como chamei esse método na minha atividade?
Milan Gajera 29/03/16

Eu tentei você postar e eu recebi um erro que eu estava postando um erro no meu blog
Milan Gajera 29/16


1

Você pode fazer isso usando a ConnectivityManagerAPI para android. Permite verificar se você está conectado à Internet e o tipo de conexão à Internet à qual está conectado. Basicamente, com ou sem medição.

Para verificar se há conexão com a internet.

ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();

Link da documentação: https://developer.android.com/training/monitoring-device-state/connectivity-status-type


Como você verifica se os dados móveis acabaram? Isso retorna verdadeiro mesmo se os dados móveis estiverem conectados e não houver saldo de dados restante na conta.
user2672052

0
private static NetworkUtil mInstance;
private volatile boolean mIsOnline;

private NetworkUtil() {
    ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
    exec.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            boolean reachable = false;
            try {
                Process process = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
                int returnVal = process.waitFor();
                reachable = (returnVal==0);
            } catch (Exception e) {
                e.printStackTrace();
            }
            mIsOnline = reachable;
        }
    }, 0, 5, TimeUnit.SECONDS);
}

public static NetworkUtil getInstance() {
    if (mInstance == null) {
        synchronized (NetworkUtil.class) {
            if (mInstance == null) {
                mInstance = new NetworkUtil();
            }
        }
    }
    return mInstance;
}

public boolean isOnline() {
    return mIsOnline;
}

Espero que o código acima o ajude, também verifique se você tem permissão de internet em seu aplicativo.


0

A maneira mais recente de fazer isso na documentação é usar o ConnectivityManagerpara consultar a rede ativa e determinar se ela possui conectividade com a Internet.

public boolean hasInternetConnectivity() {
    ConnectivityManager cm =
        (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    return (activeNetwork != null &&
                      activeNetwork.isConnectedOrConnecting());
}

Adicione essas duas permissões ao seu arquivo AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

1
Não funciona :( Como @Buda Gavril diz, se eu estiver conectado a uma rede sem fio que não tenha acesso à Internet, esse método ainda retornará verdadeiro. Teste no Xiaomi 4, Android 6.0.1.
DysaniazzZ

0

Verifique o tipo de wifi no gerenciador de conectividade:

   //check network connection
    ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean hasNetworkConnection = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
    System.out.println("Connection ? : " + hasNetworkConnection);
    //check wifi
    boolean hasWifiConnection = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
    System.out.println("Wifi ? : " + hasWifiConnection);

A documentação do Android descreve 'TYPE_WIFI' como 'Uma conexão de dados WIFI. Os dispositivos podem suportar mais de um. '


0

Uma boa solução para verificar se a rede ativa possui conexão à Internet:

public boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager
            = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager != null) {
        Network network = connectivityManager.getActiveNetwork();
        NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
        return networkCapabilities != null && networkCapabilities
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
    }
    return false;
}

0

Você pode usar o ConnectivityManager.

val cm = getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            val activeNetwork: NetworkInfo? = cm.activeNetworkInfo
            val dialogBuilder = AlertDialog.Builder(this)

            if (activeNetwork!=null) // Some network is available
            {
                if (activeNetwork.isConnected) { // Network is connected to internet

    }else{ // Network is NOT connected to internet

    }

Verifique isso e isso


0

Use a seguinte classe , atualizada para o último nível da API: 29.

// License: MIT
// http://opensource.org/licenses/MIT
package net.i2p.android.router.util;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Build;
import android.telephony.TelephonyManager;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.concurrent.CancellationException;



/**
 * Check device's network connectivity and speed.
 *
 * @author emil http://stackoverflow.com/users/220710/emil
 * @author str4d
 * @author rodrigo https://stackoverflow.com/users/5520417/rodrigo
 */
public class ConnectivityAndInternetAccessCheck {

    private static ArrayList < String > hosts = new ArrayList < String > () {
        {
            add("google.com");
            add("facebook.com");
            add("apple.com");
            add("amazon.com");
            add("twitter.com");
            add("linkedin.com");
            add("microsoft.com");
        }
    };
    /**
     * Get the network info.
     *
     * @param context the Context.
     * @return the active NetworkInfo.
     */
    private static NetworkInfo getNetworkInfo(Context context) {
        NetworkInfo networkInfo = null;
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm != null) {
            networkInfo = cm.getActiveNetworkInfo();
        }
        return networkInfo;
    }

    /**
     * Gets the info of all networks
     * @param context The context
     * @return an array of @code{{@link NetworkInfo}}
     */
    private static NetworkInfo[] getAllNetworkInfo(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getAllNetworkInfo();
    }

    /**
     * Gives the connectivity manager
     * @param context The context
     * @return the @code{{@link ConnectivityManager}}
     */
    private static ConnectivityManager getConnectivityManager(Context context) {
        return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    }

    /**
     * Check if there is any connectivity at all.
     *
     * @param context the Context.
     * @return true if we are connected to a network, false otherwise.
     */
    public static boolean isConnected(Context context) {
        boolean isConnected = false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ConnectivityManager connectivityManager = ConnectivityAndInternetAccessCheck.getConnectivityManager(context);
            Network[] networks = connectivityManager.getAllNetworks();
            networksloop: for (Network network: networks) {
                if (network == null) {
                    isConnected = false;
                } else {
                    NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
                    if(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)){
                        isConnected = true;
                        break networksloop;
                    }
                    else {
                        isConnected = false;
                    }
                }
            }

        } else {
            NetworkInfo[] networkInfos = ConnectivityAndInternetAccessCheck.getAllNetworkInfo(context);
            networkinfosloop: for (NetworkInfo info: networkInfos) {
                // Works on emulator and devices.
                // Note the use of isAvailable() - without this, isConnected() can
                // return true when Wifi is disabled.
                // http://stackoverflow.com/a/2937915
                isConnected = info != null && info.isAvailable() && info.isConnected();
                if (isConnected) {
                    break networkinfosloop;
                }
            }

        }
        return isConnected;
    }

    /**
     * Check if there is any connectivity to a Wifi network.
     *
     * @param context the Context.
     * @return true if we are connected to a Wifi network, false otherwise.
     */
    public static boolean isConnectedWifi(Context context) {
        boolean isConnectedWifi = false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ConnectivityManager connectivityManager = ConnectivityAndInternetAccessCheck.getConnectivityManager(context);
            Network[] networks = connectivityManager.getAllNetworks();
            networksloop: for (Network network: networks) {
                if (network == null) {
                    isConnectedWifi = false;
                } else {
                    NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
                    if(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)){
                        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                            isConnectedWifi = true;
                            break networksloop;
                        } else {
                            isConnectedWifi = false;
                        }
                    }
                }

            }


        } else {
            NetworkInfo[] networkInfos = ConnectivityAndInternetAccessCheck.getAllNetworkInfo(context);
            networkinfosloop: for (NetworkInfo n: networkInfos) {
                isConnectedWifi = n != null && n.isAvailable() && n.isConnected() && n.getType() == ConnectivityManager.TYPE_WIFI;
                if (isConnectedWifi) {
                    break networkinfosloop;
                }

            }
        }
        return isConnectedWifi;
    }

    /**
     * Check if there is any connectivity to a mobile network.
     *
     * @param context the Context.
     * @return true if we are connected to a mobile network, false otherwise.
     */
    public static boolean isConnectedMobile(Context context) {
        boolean isConnectedMobile = false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ConnectivityManager connectivityManager = ConnectivityAndInternetAccessCheck.getConnectivityManager(context);
            Network[] allNetworks = connectivityManager.getAllNetworks();
            networksloop: for (Network network: allNetworks) {
                if (network == null) {
                    isConnectedMobile = false;
                } else {
                    NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
                    if(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)){
                        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                            isConnectedMobile = true;
                            break networksloop;
                        } else {
                            isConnectedMobile = false;
                        }
                    }
                }

            }

        } else {
            NetworkInfo[] networkInfos = ConnectivityAndInternetAccessCheck.getAllNetworkInfo(context);
            networkinfosloop: for (NetworkInfo networkInfo: networkInfos) {
                isConnectedMobile = networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected() && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE;
                if (isConnectedMobile) {
                    break networkinfosloop;
                }
            }
        }
        return isConnectedMobile;
    }

    /**
     * Check if there is fast connectivity.
     *
     * @param context the Context.
     * @return true if we have "fast" connectivity, false otherwise.
     */
    public static boolean isConnectedFast(Context context) {
        boolean isConnectedFast = false;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            NetworkInfo[] networkInfos = ConnectivityAndInternetAccessCheck.getAllNetworkInfo(context);
            networkInfosloop:
            for (NetworkInfo networkInfo: networkInfos) {
                isConnectedFast = networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected() && isConnectionFast(networkInfo.getType(), networkInfo.getSubtype());
                if (isConnectedFast) {
                    break networkInfosloop;
                }
            }
        } else {
            throw new UnsupportedOperationException();
        }
        return isConnectedFast;
    }

    /**
     * Check if the connection is fast.
     *
     * @param type the network type.
     * @param subType the network subtype.
     * @return true if the provided type/subtype combination is classified as fast.
     */
    private static boolean isConnectionFast(int type, int subType) {
        if (type == ConnectivityManager.TYPE_WIFI) {
            return true;
        } else if (type == ConnectivityManager.TYPE_MOBILE) {
            switch (subType) {
                case TelephonyManager.NETWORK_TYPE_1xRTT:
                    return false; // ~ 50-100 kbps
                case TelephonyManager.NETWORK_TYPE_CDMA:
                    return false; // ~ 14-64 kbps
                case TelephonyManager.NETWORK_TYPE_EDGE:
                    return false; // ~ 50-100 kbps
                case TelephonyManager.NETWORK_TYPE_EVDO_0:
                    return true; // ~ 400-1000 kbps
                case TelephonyManager.NETWORK_TYPE_EVDO_A:
                    return true; // ~ 600-1400 kbps
                case TelephonyManager.NETWORK_TYPE_GPRS:
                    return false; // ~ 100 kbps
                case TelephonyManager.NETWORK_TYPE_HSDPA:
                    return true; // ~ 2-14 Mbps
                case TelephonyManager.NETWORK_TYPE_HSPA:
                    return true; // ~ 700-1700 kbps
                case TelephonyManager.NETWORK_TYPE_HSUPA:
                    return true; // ~ 1-23 Mbps
                case TelephonyManager.NETWORK_TYPE_UMTS:
                    return true; // ~ 400-7000 kbps
                /*
                 * Above API level 7, make sure to set android:targetSdkVersion
                 * to appropriate level to use these
                 */
                case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11
                    return true; // ~ 1-2 Mbps
                case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
                    return true; // ~ 5 Mbps
                case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
                    return true; // ~ 10-20 Mbps
                case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
                    return false; // ~25 kbps
                case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
                    return true; // ~ 10+ Mbps
                // Unknown
                case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                default:
                    return false;
            }
        } else {
            return false;
        }
    }

    public ArrayList < String > getHosts() {
        return hosts;
    }

    public void setHosts(ArrayList < String > hosts) {
        this.hosts = hosts;
    }
    //TODO Debug on devices
    /**
     * Checks that Internet is available by pinging DNS servers.
     */
    private static class InternetConnectionCheckAsync extends AsyncTask < Void, Void, Boolean > {

        private Context context;

        /**
         * Creates an instance of this class
         * @param context The context
         */
        public InternetConnectionCheckAsync(Context context) {
            this.setContext(context);
        }

        /**
         * Cancels the activity if the device is not connected to a network.
         */
        @Override
        protected void onPreExecute() {
            if (!ConnectivityAndInternetAccessCheck.isConnected(getContext())) {
                cancel(true);
            }
        }

        /**
         * Tells whether there is Internet access
         * @param voids The list of arguments
         * @return True if Internet can be accessed
         */
        @Override
        protected Boolean doInBackground(Void...voids) {
            return isConnectedToInternet(getContext());
        }

        @Override
        protected void onPostExecute(Boolean aBoolean) {
            super.onPostExecute(aBoolean);
        }

        /**
         * The context
         */
        public Context getContext() {
            return context;
        }

        public void setContext(Context context) {
            this.context = context;
        }
    } //network calls shouldn't be called from main thread otherwise it will throw //NetworkOnMainThreadException

    /**
     * Tells whether Internet is reachable
     * @return true if Internet is reachable, false otherwise
     * @param context The context
     */
    public static boolean isInternetReachable(Context context) {
        try {
            return new InternetConnectionCheckAsync(context).execute().get();
        } catch (CancellationException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Tells whether there is Internet connection
     * @param context The context
     * @return @code {true} if there is Internet connection
     */
    private static boolean isConnectedToInternet(Context context) {
        boolean isAvailable = false;
        if (!ConnectivityAndInternetAccessCheck.isConnected(context)) {
            isAvailable = false;
        } else {
            try {
                foreachloop: for (String h: new ConnectivityAndInternetAccessCheck().getHosts()) {
                    if (isHostAvailable(h)) {
                        isAvailable = true;
                        break foreachloop;
                    }
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }

        return isAvailable;

    }

    /**
     * Checks if the host is available
     * @param hostName
     * @return
     * @throws IOException
     */
    private static boolean isHostAvailable(String hostName) throws IOException {
        try (Socket socket = new Socket()) {
            int port = 80;
            InetSocketAddress socketAddress = new InetSocketAddress(hostName, port);
            socket.connect(socketAddress, 3000);

            return true;
        } catch (UnknownHostException unknownHost) {
            return false;
        }
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.