Mam taki, AsyncTask
któ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();
}
}
android
networking
asynchronous
Vidar Vestnes
źródło
źródło
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.Odpowiedzi:
Połączenie sieciowe / dostęp do Internetu
isConnectedOrConnecting()
(używane w większości odpowiedzi) sprawdza połączenie siecioweA) Pingowanie serwera (łatwe)
+
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)
+
bardzo szybki (w obie strony), działa na wszystkich urządzeniach, bardzo niezawodny-
nie można uruchomić w wątku interfejsu użytkownikaDziała to bardzo niezawodnie na każdym urządzeniu i jest bardzo szybkie. Musi jednak działać w osobnym zadaniu (np.
ScheduledExecutorService
LubAsyncTask
).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?
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:
AsyncTask
Przykład jednego strzałuDodatkowo:
RxJava/RxAndroid
Przykład jednego strzału (Kotlin)źródło
Jeśli urządzenie jest w trybie samolotowym (lub prawdopodobnie w innych sytuacjach, w których nie ma dostępnej sieci),
cm.getActiveNetworkInfo()
będzienull
, więc musisz dodaćnull
czek.Zmodyfikowano ( rozwiązanie Eddiego ) poniżej:
Dodaj także następujące uprawnienie do
AndroidManifest.xml
: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.źródło
context.getSystemService
bo inaczej to nie działa. Mam tu swoją wskazówkę androidhive.info/2012/07/04Nie musisz być skomplikowany. Najprostszym i ramowym sposobem jest użycie
ACCESS_NETWORK_STATE
uprawnień i wykonanie połączonej metodyMożesz również użyć,
requestRouteToHost
jeśli masz na myśli konkretny host i typ połączenia (Wi-Fi / mobilny).Będziesz także potrzebować:
w twoim manifeście Androida.
źródło
context.getSystemService
bo inaczej to nie działa. Mam tu swoją wskazówkę androidhive.info/2012/07/05getAllNetworkInfo()
jest przestarzałe w interfejsie API na poziomie 29Aby dostać się
getActiveNetworkInfo()
do pracy, musisz dodać do manifestu następujące elementy.źródło
getActiveNetworkInfo()
jest przestarzały na poziomie interfejsu API 29.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ć
lub
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ć
Oczywiście używam Context.getSystemService (Context.CONNECTIVITY_SERVICE) jako proxy do powiedzenia
źródło
sprawdź ten kod ... działało dla mnie :)
Następnie definiuję moduł obsługi:
... i uruchom test:
źródło
Znalezione na i zmodyfikowane (!) Z tego linku :
W swoim pliku manifestu dodaj co najmniej:
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:
źródło
Zrobiłem ten kod, jest najprostszy i jest po prostu wartością logiczną. przez zapytanie
if(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
INTERNET
iACCESS_NETWORK_STATE
uprawnienia.źródło
To działa dla mnie:
Aby sprawdzić dostępność sieci:
Aby zweryfikować dostęp do Internetu:
źródło
Jest więcej niż jeden sposób
Po pierwsze, najkrótszy, ale nieefektywny sposób
Potrzebne jest tylko zezwolenie stanu sieci
Następnie ta metoda
Jak widać w odpowiedziach
ConnectivityManager
jest 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łączeniaPo drugie, skuteczny sposób
Potrzebne są uprawnienia do stanu sieci i Internetu
Następnie ta klasa
Połączenie
CheckInternetAsyncTask
Niektóre objaśnienia: -
trzeba sprawdzić Internetu na
AsyncTask
, w przeciwnym razie może on rzucaćandroid.os.NetworkOnMainThreadException
w niektórych przypadkachConnectivityManager
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_204
ten 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 aplikacjiLimit czasu można zmienić w zakresie (20ms -> 2000ms), zwykle 1500ms
źródło
Ze wszystkiego, co do tej pory widziałem, najkrótszą i najczystszą drogą powinno być:
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.
źródło
Oto metoda, której używam:
Co więcej, sprawdź, czy jest „podłączony”:
Oto jak użyć tej metody:
Wymagane pozwolenie:
https://stackoverflow.com/a/16124915/950427
źródło
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.
źródło
Możesz iterować po wszystkich połączeniach sieciowych i sprawdzać, czy jest co najmniej jedno dostępne połączenie:
źródło
Dla mnie sprawdzanie stanu połączenia w klasie Activity nie było dobrą praktyką, ponieważ
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 :
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)
źródło
To działa dla mnie. Wypróbuj to.
źródło
Ta metoda daje opcję naprawdę szybkiej metody (dla informacji zwrotnej w czasie rzeczywistym) lub wolniejszej metody (dla jednorazowych kontroli wymagających niezawodności)
źródło
Używam tego kodu zamiast adresu InetAddress:
źródło
Sprawdzanie stanu połączenia z siecią Android / Internetem nie jest skomplikowane. Poniższa
DetectConnection
klasa pomoże ci sprawdzić ten status:Aby uzyskać więcej informacji, zobacz Jak sprawdzić stan sieci Android / łączności internetowej
źródło
Najlepsze podejście:
źródło
Oto kod z mojej
Utils
klasy:źródło
źródło
Możesz użyć tej metody do wykrycia dostępności sieci
źródło
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
Nazwij to teraz tak,
źródło
Jest to omówione w dokumentach Androida http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html
źródło
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
Możesz sprawdzić, czy Internet jest aktywny, używając poniższego kodu:
źródło
Bardzo ważne jest sprawdzenie, czy mamy połączenie z isAvailable () i czy jest możliwe nawiązanie połączenia z isConnected ()
i możesz zniszczyć typ aktywnej sieci Wi-Fi :
lub mobilny Móvil :
nie zapomnij uprawnień:
źródło
Kotlin i coroutines
Umieściłem funkcję w
ViewModel
, która maviewModelScope
. Za pomocą obserwowalnegoLiveData
informuję aktywność o połączeniu.ViewModel
Czynność
źródło
Wystarczy utworzyć następującą klasę, która sprawdza połączenie internetowe:
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
true
przeciwnym 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ń:
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.
źródło
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
źródło