내가 가지고 AsyncTask
호스트 이름에 대한 네트워크 액세스를 확인하도록되어 그. 그러나 doInBackground()
시간이 초과되지 않습니다. 누구나 단서가 있습니까?
public class HostAvailabilityTask extends AsyncTask<String, Void, Boolean> {
private Main main;
public HostAvailabilityTask(Main main) {
this.main = main;
}
protected Boolean doInBackground(String... params) {
Main.Log("doInBackground() isHostAvailable():"+params[0]);
try {
return InetAddress.getByName(params[0]).isReachable(30);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean... result) {
Main.Log("onPostExecute()");
if(result[0] == false) {
main.setContentView(R.layout.splash);
return;
}
main.continueAfterHostCheck();
}
}
답변
네트워크 연결 / 인터넷 액세스
isConnectedOrConnecting()
(대부분의 답변에서 사용됨) 모든 네트워크 연결을 확인 합니다- 해당 네트워크에 인터넷이 연결되어 있는지 확인하려면 다음 중 하나를 사용하십시오.
A) 서버 핑 (쉬운)
// ICMP
public boolean isOnline() {
Runtime runtime = Runtime.getRuntime();
try {
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = ipProcess.waitFor();
return (exitValue == 0);
}
catch (IOException e) { e.printStackTrace(); }
catch (InterruptedException e) { e.printStackTrace(); }
return false;
}
+
메인 스레드에서 실행할 수 있습니다
-
일부 구형 장치 (Galays S3 등)에서는 작동하지 않으며 인터넷을 사용할 수없는 경우 잠시 차단됩니다.
B) 인터넷 소켓에 연결 (고급)
// TCP/HTTP/DNS (depending on the port, 53=DNS, 80=HTTP, etc.)
public boolean isOnline() {
try {
int timeoutMs = 1500;
Socket sock = new Socket();
SocketAddress sockaddr = new InetSocketAddress("8.8.8.8", 53);
sock.connect(sockaddr, timeoutMs);
sock.close();
return true;
} catch (IOException e) { return false; }
}
+
매우 빠르고 (어느 쪽이든) 모든 장치에서 작동하며 매우 안정적입니다.
-
UI 스레드에서 실행할 수 없습니다
이것은 모든 장치에서 매우 안정적으로 작동하며 매우 빠릅니다. 그래도 별도의 작업 (예 : ScheduledExecutorService
또는 AsyncTask
) 으로 실행해야합니다 .
가능한 질문
-
정말 빠르나요?
예, 매우 빠릅니다 😉
-
인터넷에서 무언가를 테스트하는 것 외에 인터넷을 확인하는 신뢰할 수있는 방법이 없습니까?
내가 아는 한, 알려주고 답을 수정하겠습니다.
-
DNS가 다운되면 어떻게됩니까?
Google DNS (예
8.8.8.8
:)는 세계에서 가장 큰 공개 DNS입니다. 2013 년 현재 하루 1,300 억 건의 요청을 처리했습니다. 당신의 앱이 아마도 오늘의 이야기가 아닐 수도 있습니다. -
어떤 권한이 필요합니까?
<uses-permission android:name="android.permission.INTERNET" />
그냥 인터넷 액세스-놀람 ^^ (Btw 당신은 여기에 제안 된 방법 중 일부 가이 허락없이 인터넷 액세스에 대한 원격 접착제를 가질 수있는 방법에 대해 생각해 본 적이 있습니까?)
추가 : 원샷 AsyncTask
예
class InternetCheck extends AsyncTask<Void,Void,Boolean> {
private Consumer mConsumer;
public interface Consumer { void accept(Boolean internet); }
public InternetCheck(Consumer consumer) { mConsumer = consumer; execute(); }
@Override protected Boolean doInBackground(Void... voids) { try {
Socket sock = new Socket();
sock.connect(new InetSocketAddress("8.8.8.8", 53), 1500);
sock.close();
return true;
} catch (IOException e) { return false; } }
@Override protected void onPostExecute(Boolean internet) { mConsumer.accept(internet); }
}
///////////////////////////////////////////////////////////////////////////////////
// Usage
new InternetCheck(internet -> { /* do something with boolean response */ });
추가 : 원샷 RxJava/RxAndroid
예 (코 틀린)
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 */}
답변
기기가 비행기 모드 인 경우 (또는 사용 가능한 네트워크가없는 다른 상황 일 경우)로 cm.getActiveNetworkInfo()
표시 null
되므로 null
확인 을 추가해야합니다 .
아래 에서 수정 된 ( Eddie ‘s solution ) :
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
또한 다음 권한을 다음에 추가하십시오 AndroidManifest.xml
.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
하나의 다른 작은 지점은 주어진 시점에 네트워크 연결이 절대적으로 필요한 경우 netInfo.isConnected()
보다 오히려 사용하는 것이 좋습니다 netInfo.isConnectedOrConnecting
. 그러나 이것은 개별 사용 사례에 달려 있습니다.
답변
복잡 할 필요는 없습니다. 가장 간단한 프레임 워크 방식은 ACCESS_NETWORK_STATE
권한 을 사용 하고 연결된 방법을 만드는 것입니다.
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null &&
cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
또한 requestRouteToHost
특정 호스트 및 연결 유형 (wifi / mobile)을 염두에두고 사용할 수도 있습니다.
또한 다음이 필요합니다.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
당신의 안드로이드 매니페스트에서.
답변
getActiveNetworkInfo()
작업 하려면 매니페스트에 다음을 추가해야합니다.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
답변
ConnectivityManager 클래스를 살펴보십시오. 이 클래스를 사용하여 호스트의 활성 연결에 대한 정보를 얻을 수 있습니다. http://developer.android.com/reference/android/net/ConnectivityManager.html
편집 : 당신은 사용할 수 있습니다
Context.getSystemService(Context.CONNECTIVITY_SERVICE)
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
또는
Context.getSystemService(Context.CONNECTIVITY_SERVICE)
.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
반환 된 NetworkInfo 객체의 DetailedState 열거를 구문 분석합니다.
편집 편집 : 호스트에 액세스 할 수 있는지 확인하려면 다음을 사용할 수 있습니다.
Context.getSystemService(Context.CONNECTIVITY_SERVICE)
.requestRouteToHost(TYPE_WIFI, int hostAddress)
분명히, 나는 Context.getSystemService (Context.CONNECTIVITY_SERVICE)를 프록시로 사용하고 있습니다.
ConnectivityManager cm = Context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.yourMethodCallHere();
답변
이 코드를 확인하십시오 … 그것은 나를 위해 일했습니다 🙂
public static void isNetworkAvailable(final Handler handler, final int timeout) {
// ask fo message '0' (not connected) or '1' (connected) on 'handler'
// the answer must be send before before within the 'timeout' (in milliseconds)
new Thread() {
private boolean responded = false;
@Override
public void run() {
// set 'responded' to TRUE if is able to connect with google mobile (responds fast)
new Thread() {
@Override
public void run() {
HttpGet requestForTest = new HttpGet("http://m.google.com");
try {
new DefaultHttpClient().execute(requestForTest); // can last...
responded = true;
}
catch (Exception e) {
}
}
}.start();
try {
int waited = 0;
while(!responded && (waited < timeout)) {
sleep(100);
if(!responded ) {
waited += 100;
}
}
}
catch(InterruptedException e) {} // do nothing
finally {
if (!responded) { handler.sendEmptyMessage(0); }
else { handler.sendEmptyMessage(1); }
}
}
}.start();
}
그런 다음 핸들러를 정의합니다.
Handler h = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what != 1) { // code if not connected
} else { // code if connected
}
}
};
… 그리고 테스트를 시작하십시오 :
isNetworkAvailable(h,2000); // get the answser within 2000 ms
답변
에서 확인할 수 있고이에서 수정 (!) 링크 :
매니페스트 파일에서 최소한 다음을 추가하십시오.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
인터넷 액세스 권한이있을 수 있습니다. 연결성을 테스트 할 수있는 부울 함수는 다음과 같습니다.
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;
}
}