728x90
반응형
질문 : Android에서 인터넷 액세스를 확인하는 방법은 무엇입니까? InetAddress는 시간 초과되지 않습니다.
호스트 이름에 대한 네트워크 액세스를 확인해야하는 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입니다. 2018 년 현재 하루에 1 조 건이 넘는 쿼리를 처리했습니다 [1]. 여러분의 앱이 오늘의 화제가 아닐 것입니다. - 어떤 권한이 필요합니까?
그냥 인터넷 액세스-놀랍습니다 ^^ (Btw 당신은 여기에서 제안한 방법 중 일부 가이 권한없이 인터넷 액세스에 대한 원격 접착제를 가질 수 있는지 생각해 본 적이 있습니까?)<uses-permission android:name="android.permission.INTERNET" />
추가: RxJava/RxAndroid 예 (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 */}
추가: RxJava/RxAndroid 예 (Java)
public static Single<Boolean> hasInternetConnection() {
return Single.fromCallable(() -> {
try {
// Connect to Google DNS to check for connection
int timeoutMs = 1500;
Socket socket = new Socket();
InetSocketAddress socketAddress = new InetSocketAddress("8.8.8.8", 53);
socket.connect(socketAddress, timeoutMs);
socket.close();
return true;
} catch (IOException e) {
return false;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
}
///////////////////////////////////////////////////////////////////////////////////
// Usage
hasInternetConnection().subscribe((hasInternet) -> {
if(hasInternet) {
}else {
}
});
추가: AsyncTask 예
주의 : 이것은 요청을 수행하는 방법의 또 다른 예를 보여줍니다. 그러나 AsyncTask
는 더 이상 사용되지 않으므로 앱의 스레드 예약, Kotlin Coroutines, Rx 등으로 대체해야합니다.
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 */ });
출처 : https://stackoverflow.com/questions/1560788/how-to-check-internet-access-on-android-inetaddress-never-times-out
728x90
반응형
'프로그래밍 언어 > Android' 카테고리의 다른 글
Android에서 Bitmap을 Drawable로 변환하는 방법 (0) | 2021.10.05 |
---|---|
Android 활동 수명주기에 대해서 (0) | 2021.10.01 |
google-services.json 구성을 여러 버전에 따라 다르게 만드는 방법 (0) | 2021.10.01 |
Android에서 gravity와 layout_gravity의 차이점 (0) | 2021.10.01 |
Android에서 소프트웨어 키보드가 표시되는지 확인하는 방법 (0) | 2021.09.30 |