Java経由でインターネットに接続できるかどうかを確認するにはどうすればよいですか? 1つの方法は次のとおりです。
final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
... if we got here, we should have net ...
しかし、そのタスクを実行するのにもっと適切なものはありますか?特に行う必要がある場合連続チェック非常に頻繁であり、インターネット接続が失われる可能性が非常に高いですか?
実際のアプリケーションが必要とする場所に接続する必要があります。それ以外の場合は、無関係な場所(この場合はGoogle)への接続があるかどうかをテストしています。
特に、Webサービスと通信しようとしている場合、およびWebサービスを制御している場合は、何らかの安価な「ステータスを取得する」Webメソッドを用意することをお勧めします。そうすれば、「実際の」呼び出しが機能する可能性が高いかどうかについて、より良いアイデアを得ることができます。
他の場合、開いているはずのポートへの接続を開くだけで十分な場合があります-またはpingを送信します。 InetAddress.isReachable
は、ここでのニーズに適したAPIである可能性があります。
基本的に提供したコードとconnect
の呼び出しで十分です。ええ、それはちょうどGoogleが利用できないだけかもしれませんが、あなたが連絡する必要のある他のサイトがオンになっているかもしれませんが、それはどのくらいありそうですか?また、このコードは、外部リソースへのアクセスに実際に失敗した場合にのみ実行する必要があります(catch
ブロック内で、失敗の原因を特定します)ので、両方の外部リソース興味のあるおよび Googleは利用できません。ネット接続の問題がある可能性があります。
private static boolean netIsAvailable() {
try {
final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
conn.connect();
conn.getInputStream().close();
return true;
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
return false;
}
}
人々はINetAddress.isReachableの使用を提案しています。問題は、一部のサイトがICMP Pingメッセージをブロックするようにファイアウォールを構成していることです。そのため、Webサービスにアクセスできる場合でも「ping」が失敗する場合があります。
そしてもちろん、その逆も同様です。 Webサーバーがダウンしている場合でも、ホストはpingに応答する場合があります。
そしてもちろん、ローカルファイアウォールの制限により、マシンが特定の(またはすべての)Webサーバーに直接接続できない場合があります。
基本的な問題は、「インターネットに接続できる」というのは明確に定義されていない質問であり、この種のことをテストするのは難しいことです。
そのため、一般的に最も簡単なソリューションは、アプリがアクセスする必要があるものにアクセスしようとし、診断を行うために人間の知能に頼ることです。
Java 6では NetworkInterface を使用して、使用可能なネットワークインターフェイスを確認できます。つまり、次のようになります。
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface interf = interfaces.nextElement();
if (interf.isUp() && !interf.isLoopback())
return true;
}
まだ自分で試したことがありません。
このコード:
"127.0.0.1".equals(InetAddress.getLocalHost().getHostAddress().toString());
戻り値-私には-オフラインの場合はtrue
、それ以外の場合はfalse
。 (まあ、これがすべてのコンピューターに当てはまるかどうかはわかりません)。
これは、ここまでの他のアプローチよりもはるかに高速に機能します。
編集:これは、インターネット接続の「フリップスイッチ」(ラップトップ)または他のシステム定義オプションがオフの場合にのみ機能することがわかりました。つまり、システム自体はIPアドレスを検索しないことを知っています。
このコードは、確実にジョブを実行する必要があります。
try-with-resources
ステートメントは、リソースを閉じる必要はありません。
import Java.io.IOException;
import Java.net.InetSocketAddress;
import Java.net.Socket;
import Java.net.UnknownHostException;
public class InternetAvailabilityChecker
{
public static boolean isInternetAvailable() throws IOException
{
return isHostAvailable("google.com") || isHostAvailable("Amazon.com")
|| isHostAvailable("facebook.com")|| isHostAvailable("Apple.com");
}
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;
}
}
}
NetworkInterfaceを使用してネットワークを待機するコードは、固定ネットワークアドレスからDHCPに切り替えるまで機能しました。わずかな拡張により、DHCPでも機能します。
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface interf = interfaces.nextElement();
if (interf.isUp() && !interf.isLoopback()) {
List<InterfaceAddress> adrs = interf.getInterfaceAddresses();
for (Iterator<InterfaceAddress> iter = adrs.iterator(); iter.hasNext();) {
InterfaceAddress adr = iter.next();
InetAddress inadr = adr.getAddress();
if (inadr instanceof Inet4Address) return true;
}
}
}
これは、IPv4ネットワーク用のopenSuse 13.1のJava 7で機能します。元のコードの問題は、一時停止から再開した後にインターフェースが起動したが、IPv4ネットワークアドレスがまだ割り当てられていないことです。この割り当てでは、プログラムはサーバーに接続できますが、IPv6の場合の対処方法はわかりません。
URL url=new URL("http://[any domain]");
URLConnection con=url.openConnection();
/*now errors WILL arise here, i hav tried myself and it always shows "connected" so we'll open an InputStream on the connection, this way we know for sure that we're connected to d internet */
/* Get input stream */
con.getInputStream();
上記のステートメントをtry catchブロックに入れて、catchの例外がインターネット接続が確立されていないことを意味する場合。 :-)
InetAddress.isReachable
インターネット接続が存在する場合、いつかfalseを返します。
Javaでインターネットの可用性をチェックする代替方法は次のとおりです。この関数は実際のICMP ECHO
ping。
public static boolean isReachableByPing(String Host) {
try{
String cmd = "";
if(System.getProperty("os.name").startsWith("Windows")) {
// For Windows
cmd = "ping -n 1 " + Host;
} else {
// For Linux and OSX
cmd = "ping -c 1 " + Host;
}
Process myProcess = Runtime.getRuntime().exec(cmd);
myProcess.waitFor();
if(myProcess.exitValue() == 0) {
return true;
} else {
return false;
}
} catch( Exception e ) {
e.printStackTrace();
return false;
}
}
私は通常、3つのステップに分けます。
いずれかの時点で失敗した場合、適切なエラーメッセージをユーザーに提供します。
public boolean checkInternetConnection()
{
boolean status = false;
Socket sock = new Socket();
InetSocketAddress address = new InetSocketAddress("www.google.com", 80);
try
{
sock.connect(address, 3000);
if(sock.isConnected()) status = true;
}
catch(Exception e)
{
status = false;
}
finally
{
try
{
sock.close();
}
catch(Exception e){}
}
return status;
}
このコードは、接続が使用可能かどうかをテストするために使用するjUnitテストクラスに含まれています。私は常に接続を受信しますが、コンテンツの長さを確認した場合、不明な場合は-1にする必要があります。
try {
URL url = new URL("http://www.google.com");
URLConnection connection = url.openConnection();
if(connection.getContentLength() == -1){
fail("Failed to verify connection");
}
}
catch (IOException e) {
fail("Failed to open a connection");
e.printStackTrace();
}
1)アプリケーションの接続先を把握します。
2)ワーカープロセスを設定して InetAddress.isReachable をチェックし、そのアドレスへの接続を監視します。
Gradleオプション--offline
もありますが、これはおそらくあなたが望む振る舞いをもたらすでしょう。
次のコードを使用すると、Androidデバイスでネットワークのステータスを取得できます
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView mtv=findViewById(R.id.textv);
ConnectivityManager connectivityManager=
(ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(((Network)connectivityManager.getActiveNetwork())!=null)
mtv.setText("true");
else
mtv.setText("fasle");
}
}
}