Jak sprawdzić dostęp do Internetu na Androidzie? Adres InetAddress nigdy się nie kończy

657

Mam taki, AsyncTaskktóry ma sprawdzić dostęp sieciowy do nazwy hosta. Ale doInBackground()nigdy nie upłynął limit czasu. Czy ktoś ma jakiś pomysł?

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();
    }   
}
Vidar Vestnes
źródło
5
Aby sprawdzić połączenie z Internetem, prawdopodobnie najbardziej niezawodnym sposobem byłoby pingowanie jednego z głównych serwerów nazw, można to zrobić na przykład za pomocą if(Runtime.getRuntime().exec("/system/bin/ping -c 1 8.8.8.8").waitFor()==0) .... Zobacz moją odpowiedź na lepszą implementację tego. Przy okazji zaakceptowanej odpowiedzi (i wielu innych tutaj) po prostu sprawdź połączenie sieciowe , a nie Internet.
Lewita
4
Nie używaj metody ping, zamiast tego użyj sprawdzenia HTTP. ICMP jest zablokowany w niektórych sieciach, więc ping nie będzie działał. Np .: działa doskonale na moim domowym Wi-Fi, ale nie działa, gdy używam danych mobilnych w sieci Vodafone (na Węgrzech). Lub połącz obie metody jako rezerwowe, ale bądź ostrożny, ponieważ waitFor () poczeka około 20 sekund, nawet jeśli użyjesz -w lub -W.
Tamás Bolvári,
@ TamásBolvári: Jeszcze lepiej byłoby poradzić sobie z tym na warstwie tcp. Co powinno zbliżyć cię do szybkości ICMP, przy niezawodności żądania HTTP. Zredagowałem odpowiednio „odpowiedź ping”.
Lewita

Odpowiedzi:

552

Połączenie sieciowe / dostęp do Internetu

  • isConnectedOrConnecting()(używane w większości odpowiedzi) sprawdza połączenie sieciowe
  • Aby dowiedzieć się, czy którakolwiek z tych sieci ma dostęp do Internetu , skorzystaj z jednego z poniższych

A) Pingowanie serwera (łatwe)

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

+ może działać na głównym wątku

- nie działa na niektórych starych urządzeniach (Galays S3 itp.), blokuje chwilę, jeśli nie ma dostępu do Internetu.

B) Połącz się z gniazdem w Internecie (zaawansowane)

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

+bardzo szybki (w obie strony), działa na wszystkich urządzeniach, bardzo niezawodny

- nie można uruchomić w wątku interfejsu użytkownika

Działa to bardzo niezawodnie na każdym urządzeniu i jest bardzo szybkie. Musi jednak działać w osobnym zadaniu (np. ScheduledExecutorServiceLub AsyncTask).

Możliwe pytania

  • Czy to naprawdę wystarczająco szybko?

    Tak, bardzo szybko ;-)

  • Czy nie ma innego wiarygodnego sposobu na sprawdzenie Internetu niż testowanie czegoś w Internecie?

    Nie, o ile wiem, ale daj mi znać, a ja zredaguję swoją odpowiedź.

  • Co jeśli DNS nie działa?

    Google DNS (np. 8.8.8.8) Jest największym publicznym DNS na świecie. W 2013 r. Dziennie obsługiwało 130 miliardów zamówień. Powiedzmy, że Twoja aplikacja prawdopodobnie nie byłaby najważniejsza.

  • Jakie uprawnienia są wymagane?

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

    Po prostu dostęp do Internetu - niespodzianka ^^ (Btw, czy kiedykolwiek zastanawiałeś się, w jaki sposób niektóre sugerowane tutaj metody mogą mieć nawet zdalny klej na dostęp do Internetu, bez tego pozwolenia?)

 

Dodatkowo: AsyncTaskPrzykład jednego strzału

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 */ });

Dodatkowo: RxJava/RxAndroidPrzykład jednego strzału (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 */}
Lewita
źródło
22
To jest wielki spokój kodu! Uważam, że jest to bardzo przydatne na urządzeniach korzystających z kart przedpłaconych! Kiedy zabraknie im pieniędzy, mają dostęp do Internetu, ale nie ma internetu. Więc samo sprawdzanie łączności nie zadziałałoby. DZIĘKUJĘ CI!
Blejzer
10
Pamiętaj, że to podejście jest blokujące, więc nie powinieneś go wykonywać w interfejsie użytkownika
Sergii
36
@Levit To powinna być zaakceptowana odpowiedź. Powyższa odpowiedź sprawdza tylko sieć n NIE POŁĄCZENIE INTERNETOWE . I tak, to jest bardzo szybkie. Dzięki. Stąd głosowanie.
Roon13
9
To rozwiązanie nie działa na wszystkich urządzeniach. Niektóre urządzenia zawsze zwracają 2, jak stwierdził @Salmaan. Testowane przeze mnie urządzenia miały połączenie z Internetem, a celem pingowania jest serwer Google DNS, który odpowiada na żądania ping. Myślę, że niektórzy dostawcy nie zezwalają na żądania ping. Na przykład testowałem na tablecie Samsung 10.1 (4.3), a rozwiązanie nie działa. Kiedy uruchamiam polecenie ping za pomocą narzędzia wiersza polecenia, pojawia się błąd uprawnień. Polecenie nie działa również na emulatorach. Ostrożnie korzystaj z tego rozwiązania.
Eren Yilmaz
9
To podejście nie działa na wszystkich telefonach. Nie działa na przykład w Samsung Galaxy S3. Zobacz tutaj: Dlaczego ping działa na niektórych urządzeniach, a nie na innych?
Adil Hussain
1032

Jeśli urządzenie jest w trybie samolotowym (lub prawdopodobnie w innych sytuacjach, w których nie ma dostępnej sieci), cm.getActiveNetworkInfo()będzie null, więc musisz dodać nullczek.

Zmodyfikowano ( rozwiązanie Eddiego ) poniżej:

public boolean isOnline() {
    ConnectivityManager cm =
        (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    return netInfo != null && netInfo.isConnectedOrConnecting();
}

Dodaj także następujące uprawnienie do AndroidManifest.xml:

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

Jeszcze jeden mały punkt, jeśli absolutnie potrzebujesz połączenia sieciowego w danym momencie, to może być lepiej użyć netInfo.isConnected()niż netInfo.isConnectedOrConnecting. Myślę jednak, że to zależy od indywidualnego przypadku użycia.

gar
źródło
109
imo nadal powinieneś i musisz sprawdzić wyjątki limitu czasu http, ponieważ mogą wystąpić sytuacje, gdy sieć jest podłączona, ale nie byłoby rzeczywistego połączenia z Internetem, ponieważ jedynym sposobem na uzyskanie dostępu jest połączenie VPN, na przykład przez VPN - w ten sposób na przykład połączenie WI-FI, ale brak rzeczywistego ruchu internetowego. Inną sytuacją jest zawieszenie się serwera. To są dwa problemy, które ostatnio uruchomiłem i menedżer połączeń nie pomoże.
północ
21
Zgadzam się z północą i Pintu, ta odpowiedź nie powinna być zaakceptowaną odpowiedzią, nie ma nic wspólnego ze sprawdzaniem, czy jesteś w Internecie. Na przykład, jeśli telefon jest podłączony do sieci Wi-Fi za pomocą specjalnego portalu, np. W hotelu, ta funkcja niepoprawnie zwróci wartość true. Prawidłowa odpowiedź to pingowanie serwera w publicznym Internecie.
Miguel
9
gdy nie ma działającego internetu dla mojego routera, jeśli połączę się z routerem przez Wi-Fi, powyższy kod zwraca wartość true. Ale tak nie powinno być, prawda? Czy możesz mi pomóc
MoHaN K RaJ
5
Musiałem dodać kontekst, context.getSystemServicebo inaczej to nie działa. Mam tu swoją wskazówkę androidhive.info/2012/07/04
Francisco Corrales Morales
1
Dobry sposób na sprawdzenie dostępności sieci. Ale jak sprawdzić dostęp do Internetu?
Tamás Bolvári
296

Nie musisz być skomplikowany. Najprostszym i ramowym sposobem jest użycie ACCESS_NETWORK_STATEuprawnień i wykonanie połączonej metody

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

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

Możesz również użyć, requestRouteToHostjeśli masz na myśli konkretny host i typ połączenia (Wi-Fi / mobilny).

Będziesz także potrzebować:

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

w twoim manifeście Androida.

Eddie
źródło
82
lepiej jest wykonać kontrolę zerową na poziomie cm.getActiveNetworkInfo (), wyrzuciło zero, jeśli żadna aktywna sieć nie była dostępna.
Samuel
zobacz stackoverflow.com/a/11691676/1979773, aby uzyskać głębsze wyjaśnienie dotyczące requestRouteToHost ()
Spartako,
Musiałem dodać kontekst, context.getSystemServicebo inaczej to nie działa. Mam tu swoją wskazówkę androidhive.info/2012/07/05
Francisco Corrales Morales
9
To rozwiązanie zwróci wartość true, jeśli jesteś podłączony do hotspotu Wi-Fi, nawet jeśli ten hotspot NIE ma połączenia z Internetem.
Josh
63

Aby dostać się getActiveNetworkInfo()do pracy, musisz dodać do manifestu następujące elementy.

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
azelez
źródło
To zdecydowanie powinno znaleźć się pod prawidłową odpowiedzią (zmarnować zbyt dużo czasu na zastanawianie się, co do diabła jest nie tak).
Indrek Kõue
2
Zezwolenie na INTERNET nie jest do tego potrzebne, wystarczy ACCESS_NETWORK_STATE. INTERNET jest potrzebny tylko wtedy, gdy faktycznie nawiążesz połączenia ze zdalnymi lokalizacjami, nie sprawdzając stanu radia urządzenia.
Tom
3
Twoja odpowiedź nie jest obecnie tak naprawdę odpowiedzią, jest jedynie niewielkim dodatkiem do innych odpowiedzi. Jeśli wszystkie inne odpowiedzi nie byłyby tutaj, czy Twoja odpowiedź miałaby sens? Nie całkiem. Bo jeśli tak, lepiej rozszerzyć swoją odpowiedź kodem, jak jej użyć, lub usunąć swoją odpowiedź i dodać informacje w innej odpowiedzi (nie stracisz żadnej reputacji)
Tim
Uważaj getActiveNetworkInfo()jest przestarzały na poziomie interfejsu API 29.
Przepełnienie stosu
46

Spójrz na klasę ConnectivityManager. Możesz użyć tej klasy, aby uzyskać informacje o aktywnych połączeniach na hoście. http://developer.android.com/reference/android/net/ConnectivityManager.html

EDYCJA: Możesz użyć

Context.getSystemService(Context.CONNECTIVITY_SERVICE)
    .getNetworkInfo(ConnectivityManager.TYPE_MOBILE) 

lub

Context.getSystemService(Context.CONNECTIVITY_SERVICE)
    .getNetworkInfo(ConnectivityManager.TYPE_WIFI) 

i przeanalizuj wyliczenie szczegółowyState zwróconego obiektu NetworkInfo

EDYCJA EDYCJA: Aby dowiedzieć się, czy możesz uzyskać dostęp do hosta, możesz użyć

Context.getSystemService(Context.CONNECTIVITY_SERVICE)
    .requestRouteToHost(TYPE_WIFI, int hostAddress)

Oczywiście używam Context.getSystemService (Context.CONNECTIVITY_SERVICE) jako proxy do powiedzenia

ConnectivityManager cm = Context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.yourMethodCallHere();
Chinmay Kanchi
źródło
Nie jestem pewien, ale wydaje się, że to kod do testowania, jakiego rodzaju połączenia sieciowego jestem obecnie na Np. Jestem na Wi-Fi, nie ma gwarancji, że domowy router Wi-Fi jest podłączony do Internetu ... aby sprawdzić, czy rzeczywiście musisz wysłać zapytanie do
serwera
1
W sekcji EDYCJA EDYCJI wystąpił błąd, pominąłem wywołanie requestRouteToHost (). Przeczytaj ponownie odpowiedź teraz :)
Chinmay Kanchi
requestRouteToHost został uznany za przestarzały.
Jahaziel
46

sprawdź ten kod ... działało dla mnie :)

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

Następnie definiuję moduł obsługi:

Handler h = new Handler() {
    @Override
    public void handleMessage(Message msg) {

        if (msg.what != 1) { // code if not connected

        } else { // code if connected

        }   
    }
};

... i uruchom test:

isNetworkAvailable(h,2000); // get the answser within 2000 ms
Gilbou
źródło
3
Co to jest Google nie działa? Wymaga to również pozwolenia na INTERNET, co nie jest konieczne dla danego zadania. Wreszcie, to zużywa dane (nawet jeśli są nieistotne). To po prostu wygląda na taką kludge.
Tom
28
@Tom, żeby być uczciwym, to prawdopodobnie jedyna poprawna odpowiedź. Pozostałe przykłady pokazują jedynie, czy połączenie sieciowe jest dostępne i / lub czy istnieje połączenie z tą siecią, ale nie odpowiadaj na pytanie, czy sieć ta może faktycznie nawiązać również połączenie zdalne (na przykład ze stroną internetową). Odpowiada to na plakaty Q, a inne odpowiedzi nie
slinden77
2
@dmmh Tak, to niestety prawda z tego, co widziałem z interfejsami API Androida. Być może prosty ping może być lepiej, stackoverflow.com/questions/3905358/... . Jeśli naprawdę się martwisz, możesz nawet dołączyć listę adresów IP do pingowania, ponieważ chociaż istnieje bardzo mała szansa, że ​​Google kiedykolwiek spadnie, istnieje jeszcze mniejsza szansa, że ​​Google, Bing i Yahoo spadną tego samego dnia . Tylko moje myśli.
Tom
10
Nie ma sensu przeprowadzać tej kontroli. Jeśli zamierzasz poświęcić czas systemowy i zasoby sieciowe, aby połączyć się z Google, mógłbyś spędzić je zamiast połączyć się z zasobem, na którym ci zależy.
Benjamin
16
W Chinach Google został zablokowany !!
Anthone
26

Znalezione na i zmodyfikowane (!) Z tego linku :

W swoim pliku manifestu dodaj co najmniej:

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

Prawdopodobnie masz już uprawnienie do INTERNETU, jeśli masz do niego dostęp. Następnie funkcją logiczną, która pozwala na testowanie łączności, jest:

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;
    }
}
Ajhar
źródło
18

Zrobiłem ten kod, jest najprostszy i jest po prostu wartością logiczną. przez zapytanieif(isOnline()){

Otrzymasz, jeśli istnieje połączenie i jeśli można połączyć się ze stroną, kod stanu 200(stabilne połączenie).

Upewnij się, aby dodać poprawne INTERNETi ACCESS_NETWORK_STATEuprawnienia.

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;
}
Android.Thirio.nl
źródło
6
Może powinieneś zamienić 200 na HttpURLConnection.HTTP_OK
Yash
5
Co jeśli Google nie działa?
Yauraw Gadav
12

To działa dla mnie:

Aby sprawdzić dostępność sieci:

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

Aby zweryfikować dostęp do Internetu:

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;
}
Musculaa
źródło
jest to świetne rozwiązanie, aby sprawdzić, czy serwer działa, działa naprawdę dobrze. dzięki!
Williew
1
isOnline () nie powinien w ogóle działać na głównym wątku, ponieważ jeśli jest sygnał Wi-Fi, ale nie ma internetu, zajmie to zbyt długo i zablokuje główny wątek.
humazed
9

Jest więcej niż jeden sposób

Po pierwsze, najkrótszy, ale nieefektywny sposób

Potrzebne jest tylko zezwolenie stanu sieci

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

Następnie ta metoda

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

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        boolean isConnected = activeNetwork != null &&
                activeNetwork.isConnected();

        return isConnected;

    }

Jak widać w odpowiedziach ConnectivityManagerjest to rozwiązanie, właśnie dodałem je w ramach metody, której wszyscy używają
ConnectivityManager zwracają wartość true, jeśli istnieje dostęp do sieci, a nie dostęp do Internetu, oznacza to, że Wi-Fi jest podłączone do routera, ale router nie ma Internetu zwraca true, sprawdza dostępność połączenia

Po drugie, skuteczny sposób

Potrzebne są uprawnienia do stanu sieci i Internetu

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

Następnie ta klasa

 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
            }

        }


    }

Połączenie CheckInternetAsyncTask

new CheckInternetAsyncTask(getApplicationContext()).execute();

Niektóre objaśnienia: -

  • trzeba sprawdzić Internetu na AsyncTask, w przeciwnym razie może on rzucać android.os.NetworkOnMainThreadExceptionw niektórych przypadkach

  • ConnectivityManager służy do sprawdzania dostępu do sieci, jeśli true wysyła żądanie (Ping)

  • Żądanie wysłania na http://clients3.google.com/generate_204ten znany adres URL zwraca pustą stronę o statusie HTTP 204, jest to szybsze i bardziej wydajne niż http://www.google.com, przeczytaj to . jeśli masz witrynę, najlepiej jest umieścić ją zamiast Google, tylko jeśli korzystasz z niej w aplikacji

  • Limit czasu można zmienić w zakresie (20ms -> 2000ms), zwykle 1500ms

Mohamed Embaby
źródło
2
Świetne pytanie, to smutne, że nie masz więcej punktów. To musi być poprawna odpowiedź.
Jhon Fredy Trujillo Ortega
Jestem nowy na Androida. jednak ta odpowiedź jest dobrze ujęta i zyskuje większą uwagę @ 7569106
Mazen Embaby
1
najlepsza i pełna odpowiedź, dziękuję. jeśli ktoś ma stronę internetową, zauważy, że warunek musi polubić ten urlc.getResponseCode () == 200 i nie musi sprawdzać urlc.getContentLength () == 0
AREF
twoja druga opcja
ulega
zawiesza aplikację
nafees ahmed
8

Ze wszystkiego, co do tej pory widziałem, najkrótszą i najczystszą drogą powinno być:

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: To nie pinguje żadnego hosta, po prostu sprawdza status połączenia, więc jeśli router nie ma połączenia z Internetem, a urządzenie jest z nim połączone, metoda zwróciłaby wartość true, mimo że nie masz dostępu do Internetu.
Do rzeczywistego testu polecam wykonanie żądania HttpHead (np. Na www.google.com) i sprawdzenie stanu, jeśli 200 OK wszystko jest w porządku, a twoje urządzenie ma połączenie z Internetem.

Mikołaj
źródło
Chciałem umieścić tę metodę w klasie globalnej, więc musiałem użyć tej wersji, aby przekazać kontekst z działania, z którego go wywoływałem. Dzięki!
RyanG
8

Oto metoda, której używam:

public boolean isNetworkAvailable(final Context context) {
    return ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo() != null;
}

Co więcej, sprawdź, czy jest „podłączony”:

public boolean isNetworkAvailable(final Context context) {
    final ConnectivityManager connectivityManager = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
    return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected();
}

Oto jak użyć tej metody:

if (isNetworkAvailable(context)) {
    // code here
} else {
    // code
}

Wymagane pozwolenie:

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

https://stackoverflow.com/a/16124915/950427

Jared Burrows
źródło
7

Jeden ważny przypadek użycia na urządzeniach mobilnych, aby zapewnić faktyczne połączenie. Jest to powszechny problem, gdy użytkownik mobilny wchodzi do sieci Wi-Fi z „Captive Portal”, w którym musi się zalogować. Korzystam z tej funkcji blokowania w tle, aby zapewnić połączenie.

/*
 * 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;
}
użytkownik1528493
źródło
3
+1 za faktycznie sprawdzanie łączności typu end-to-end. Jednak w przypadku „Captive Portal” zauważyłem, że wielu z nich przejdzie powyższy test, nawet jeśli się nie zalogujesz - otrzymasz stronę logowania i 200 odpowiedzi bez względu na adres URL, o który prosisz. Więc próbuję trafić na stronę w mojej własnej domenie, o której wiem, że nie istnieje, i upewnić się, że dostanę 404. Alternatywnie, możesz trafić na znaną istniejącą stronę, upewnij się, że masz 200, i sprawdź zawartość, która jest zwracane, aby upewnić się, że jest to oczekiwane.
GreyBeardedGeek
6

Możesz iterować po wszystkich połączeniach sieciowych i sprawdzać, czy jest co najmniej jedno dostępne połączenie:

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;
}
Emre Yazici
źródło
6

Dla mnie sprawdzanie stanu połączenia w klasie Activity nie było dobrą praktyką, ponieważ

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

powinien zostać tam wywołany, lub musisz zepchnąć instancję Activity (kontekst) do klasy procedury obsługi połączenia, aby móc tam sprawdzić stan połączenia Gdy nie ma dostępnego połączenia (Wi-Fi, sieć), wychwytuję wyjątek 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();
}

W ten sposób mogę obsłużyć tę sprawę wraz z innymi sprawami z tej samej klasy (mój serwer zawsze odpowiada z powrotem ciągiem json)

HiB
źródło
6

To działa dla mnie. Wypróbuj to.

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());
}}
selva_pollachi
źródło
Ta odpowiedź nie może teraz działać, ponieważ nie możemy teraz uzyskać dostępu do sieci w głównym wątku.
正宗 白 布鞋
1
Mam na myśli od poziomu API 11, to nie działa. Powód: developer.android.com/reference/android/os/… . Jeśli to działa, oznacza to, że uruchamiasz ten kod na starym urządzeniu z Androidem. (przed GB).
正宗 白 布鞋
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder () .permitAll (). Build (); StrictMode.setThreadPolicy (policy); dodaj te dwa wiersze dwa swój program, aby uniknąć wyjątku głównego wątku sieciowego
selva_pollachi
Ok, nie powinienem powiedzieć, że to nie działa, powinienem powiedzieć, że może działać (przez starą wersję docelową lub konfigurację Strictmode), ale jest odradzane. Może to łatwo spowodować ANR. (Przy tak wysokiej konfiguracji limitu czasu w HttpURLConnection)
正宗白布鞋
tak ... masz rację .. po prostu to położyłem, ponieważ jest to również jedna ze sposobów.
selva_pollachi
6

Ta metoda daje opcję naprawdę szybkiej metody (dla informacji zwrotnej w czasie rzeczywistym) lub wolniejszej metody (dla jednorazowych kontroli wymagających niezawodności)

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;
}
WonderWorker
źródło
5

Używam tego kodu zamiast adresu 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();
    }
Vidar Vestnes
źródło
Byłoby wspaniale, gdybyś wyjaśnił, czy wyjątek IOException oznacza brak połączenia z Internetem i jak niezawodne może być.
Milad.Nozari
5

Sprawdzanie stanu połączenia z siecią Android / Internetem nie jest skomplikowane. Poniższa DetectConnectionklasa pomoże ci sprawdzić ten status:

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

Aby uzyskać więcej informacji, zobacz Jak sprawdzić stan sieci Android / łączności internetowej

JSupport
źródło
5

Najlepsze podejście:

public static boolean isOnline() {
    try {
    InetAddress.getByName("google.com").isReachable(3);

    return true;
    } catch (UnknownHostException e){
    return false;
    } catch (IOException e){
    return false;
    }
    }
Lo Juego
źródło
1
Podoba mi się to podejście, ale muszę wskazać kilka rzeczy. isReachable () zwraca wartość logiczną, dlatego zamiast zwracać wartość true w sekcji try, można to zrobić tak jak wartość logiczna connected = InetAddress.getByName („google.com”). isReachable (3); następnie wróć podłączony. Ponadto isReacheable zgłasza wyjątki IOException i IllegalArgumentException, dlatego dobrym pomysłem będzie zastąpienie UnknownHostException IllegalArgumentException i włączenie trzeciego catch: catch (Exception E).
Yash
2
Ale następnie isReachable używa ICMP, który może wymagać uprawnień roota i używa portu 7, który zwykle nie ma uruchomionych usług w najnowszych systemach. Dlatego najlepszym sposobem sprawdzenia trasy do usługi online jest zwykły protokół TCP; stąd głosowanie w dół.
Yash
5

Oto kod z mojej Utilsklasy:

public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivityManager 
              = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
Mahendra Liya
źródło
5
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();
}

}
użytkownik2912903
źródło
Podobnie jak wszystkie inne, które nie przeczytały problemu, nie rozwiązuje to problemu, ponieważ tak naprawdę nie sprawdza połączenia z Internetem. Połączenie z lokalnym hotspotem Wi-Fi zwróci wartość true, nawet jeśli hotspot nie pozwoli ci na przejście do Internetu.
Pedro Pombeiro
5

Możesz użyć tej metody do wykrycia dostępności sieci

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;
    }
Akshay Paliwal
źródło
5

Zastosowałem rozwiązanie dostarczone przez @Levit i utworzyłem funkcję, która nie wywoła dodatkowego żądania HTTP.

To rozwiąże błąd 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;
}

Nazwij to teraz tak,

if (!isInternetAvailable(getActivity())) {
     //Show message
} else {
     //Perfoem the api request
}
Jaymin Panchal
źródło
4

Jest to omówione w dokumentach Androida http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html

kreker
źródło
1
Ale opisana tam metoda tak naprawdę nie sprawdza połączenia z Internetem, po prostu sprawdza, czy połączenie zostało nawiązane (czy ma dostęp do Internetu, czy nie). Tytuł tego oficjalnego dokumentu jest naprawdę mylący.
Tiago,
2
Udzielenie odpowiedzi na pytanie jest lepsze niż publikowanie linku do informacji. Co jeśli link przestanie działać? Nie będziemy mieli odpowiedzi.
Jose Llausas,
4

Przejrzałem wszystkie odpowiedzi i wymyśliłem własną odpowiedź, która najpierw sprawdza, czy Internet jest dostępny, a jeśli jest dostępny, to sprawdza, czy jest on aktywny, czy nie.

Podałem wszystkie niezbędne metody i klasy, aby sprawdzić aktywne połączenie z Internetem.

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

Możesz sprawdzić, czy Internet jest aktywny, używając poniższego kodu:

 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);
            }
        });
    }
Rajesz
źródło
Lepsze nawiązywanie wątków w pakiecie w NetworkUtils i dlatego „zmuszaj” programistę do nieużywania twojej metody
Ewoks
Aby usunąć jeden dodatkowy, jeśli warunek. if ((NetworkUtils.isInternetActiveWithPing () == NetworkUtils.STATUS_CONNECTED) || NetworkUtils.isInternetActiveWithInetAddress ()) {// Wykonaj operację sieciową} else {// Komunikat o błędzie}
Jawad Zeb
4

Bardzo ważne jest sprawdzenie, czy mamy połączenie z isAvailable () i czy jest możliwe nawiązanie połączenia z 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();
}

i możesz zniszczyć typ aktywnej sieci Wi-Fi :

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

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

nie zapomnij uprawnień:

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   <uses-permission android:name="android.permission.INTERNET" />
Jorgesys
źródło
Ładne podsumowanie składników łączności urządzenia, wystarczy owinąć je w instrukcje try / catch, aby uniknąć awarii. Podobnie, po prostu rutynowo wykonuj połączenia HttpURLConnection, o ile są one zapakowane w obsługę błędów, wkrótce będziesz wiedział, czy masz połączenie z Internetem
rangi
4

Kotlin i coroutines

Umieściłem funkcję w ViewModel, która ma viewModelScope. Za pomocą obserwowalnego LiveDatainformuję aktywność o połączeniu.

ViewModel

 fun checkInternetConnection() {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                try {
                    val timeoutMs = 3000
                    val socket = Socket()
                    val socketAddress = InetSocketAddress("8.8.8.8", 53)

                    socket.connect(socketAddress, timeoutMs)
                    socket.close()

                    withContext(Dispatchers.Main) {
                        _connection.value = true
                    }
                }
                catch(ex: IOException) {
                    withContext(Main) {
                        _connection.value = false
                    }
                }
            }
        }
    }
 private val _connection = MutableLiveData<Boolean>()
 val connection: LiveData<Boolean> = _connection

Czynność

 private fun checkInternetConnection() {
     viewModel.connection.observe(this) { hasInternet ->
         if(!hasInternet) {
             //hasn't connection
         }
         else {
            //has connection
         }
     }
  }
Jastrzębi
źródło
3

Wystarczy utworzyć następującą klasę, która sprawdza połączenie internetowe:

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

Ta klasa zawiera po prostu metodę, która zwraca wartość logiczną statusu połączenia. Dlatego w prostych słowach, jeśli metoda znajdzie prawidłowe połączenie z Internetem, w trueprzeciwnym razie zwracana jest wartośćfalse jeśli nie zostanie znalezione prawidłowe połączenie.

Następująca metoda w MainActivity wywołuje następnie wynik z poprzednio opisanej metody i zachęca użytkownika do podjęcia odpowiednich działań:

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.");
        }
    }

W powyższym kodzie, jeśli wynik jest fałszywy (dlatego nie ma połączenia z Internetem, użytkownik zostaje przeniesiony do panelu Wi-Fi Androida, gdzie jest monitowany o połączenie z hotspotem Wi-Fi.

Michele La Ferla
źródło
3

Aktualizacja 29.06.2015 Jeśli używasz Xamarin.Android i chcesz sprawdzić łączność, możesz użyć pakietu Nuget, który zapewniłby tę funkcjonalność na wielu platformach. Dobrzy kandydaci są tu i tutaj . [Koniec aktualizacji]

Powyższe odpowiedzi są całkiem dobre, ale wszystkie są w Javie i prawie wszystkie z nich sprawdzają łączność. W moim przypadku musiałem mieć połączenie z konkretnym typem połączenia i rozwijam się na Xamarin.Android. Ponadto nie przekazuję odniesienia do moich działań Kontekst w warstwie sprzętowej, używam kontekstu aplikacji. Oto moje rozwiązanie, na wypadek gdyby ktoś przyszedł z podobnymi wymaganiami. Jednak nie przeprowadziłem pełnego testowania, zaktualizuję odpowiedź, kiedy skończę testowanie

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
    }
Ma AlTaiar
źródło