Wie können Sie prüfen, ob Sie über Java eine Verbindung zum Internet herstellen können? Ein Weg wäre:
final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
... if we got here, we should have net ...
Aber gibt es etwas Passenderes, um diese Aufgabe auszuführen, besonders wenn Sie aufeinander folgende Überprüfungen durchführen müssen sehr oft und ein Verlust der Internetverbindung sehr wahrscheinlich ist?
Sie sollten eine Verbindung zu dem Ort herstellen, den Ihre aktuelle Anwendung benötigt. Ansonsten testest du, ob du eine Verbindung zu irgendwo irrelevant hast (Google in diesem Fall).
Insbesondere wenn Sie versuchen, mit einem Webdienst zu sprechen, und wenn Sie die Kontrolle über den Webdienst haben, wäre es eine gute Idee, eine billige Webmethode "get the status" zu haben. Auf diese Weise haben Sie eine viel bessere Vorstellung davon, ob Ihr "richtiger" Anruf wahrscheinlich funktioniert.
In anderen Fällen reicht es möglicherweise aus, eine Verbindung zu einem Port zu öffnen, der geöffnet sein sollte, oder ein Ping zu senden. InetAddress.isReachable
ist hier möglicherweise eine geeignete API für Ihre Anforderungen.
Der Code, den Sie im Grunde angegeben haben, sowie ein Aufruf von connect
sollten ausreichen. Ja, es könnte sein, dass nur Google nicht verfügbar ist, aber eine andere Website, die Sie kontaktieren müssen, ist, aber wie wahrscheinlich ist das? Außerdem sollte dieser Code nur ausgeführt werden, wenn Sie tatsächlich nicht auf Ihre externe Ressource zugreifen (in einem catch
-Block, um herauszufinden, was die Ursache des Fehlers war). Ich würde also sagen, dass sowohl Ihre externe Ressource als auch Google ist nicht verfügbar. Es besteht die Möglichkeit, dass Sie ein Problem mit der Netzkonnektivität haben.
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;
}
}
Die Leute haben vorgeschlagen, INetAddress.isReachable zu verwenden. Das Problem ist, dass einige Sites ihre Firewalls so konfigurieren, dass sie ICMP-Ping-Nachrichten blockieren. Ein "Ping" schlägt daher möglicherweise fehl, obwohl auf den Webdienst zugegriffen werden kann.
Und natürlich gilt auch das Gegenteil. Ein Host kann auf einen Ping antworten, auch wenn der Webserver inaktiv ist.
Natürlich kann eine Maschine aufgrund lokaler Firewall-Einschränkungen möglicherweise keine direkte Verbindung zu bestimmten (oder allen) Webservern herstellen.
Das grundlegende Problem besteht darin, dass "eine Verbindung zum Internet hergestellt werden kann" eine schlecht definierte Frage ist und diese Art von Dingen schwer zu testen ist, ohne:
Im Allgemeinen besteht die einfachste Lösung darin, dass eine App nur versucht, auf das zuzugreifen, auf was sie zugreifen muss, und auf die menschliche Intelligenz zurückzugreifen, um die Diagnose zu stellen.
Wenn Sie Java 6 verwenden, können Sie NetworkInterface verwenden, um nach verfügbaren Netzwerkschnittstellen zu suchen . I.e. etwas wie das:
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface interf = interfaces.nextElement();
if (interf.isUp() && !interf.isLoopback())
return true;
}
Ich habe es selbst noch nicht probiert.
Dieser Code sollte die Arbeit zuverlässig erledigen.
Beachten Sie, dass wir bei Verwendung der Anweisung try-with-resources
die Ressourcen nicht schließen müssen.
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;
}
}
}
Dieser Code:
"127.0.0.1".equals(InetAddress.getLocalHost().getHostAddress().toString());
Gibt - an mich - true
zurück, wenn offline, und false
, ansonsten. (Nun, ich weiß nicht, ob dies für alle Computer gilt).
Dies funktioniert viel schneller als die anderen Ansätze hier oben.
BEARBEITEN: Ich fand das nur funktionierend, wenn der "Flip-Schalter" (auf einem Laptop) oder eine andere vom System definierte Option für die Internetverbindung deaktiviert ist. Das System selbst weiß, dass es keine IP-Adressen sucht.
Der Code, der NetworkInterface verwendet, um auf das Netzwerk zu warten, funktionierte für mich, bis ich von einer festen Netzwerkadresse zu DHCP wechselte. Eine geringfügige Verbesserung macht es auch mit DHCP möglich:
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;
}
}
}
Dies funktioniert für Java 7 in openSuse 13.1 für IPv4-Netzwerke. Das Problem mit dem ursprünglichen Code besteht darin, dass die IPv4-Netzwerkadresse noch nicht zugewiesen wurde, obwohl die Schnittstelle nach dem Wiederaufnehmen der Unterbrechung aktiv war. Nach dem Warten auf diese Zuweisung kann das Programm eine Verbindung zu Servern herstellen. Aber ich habe keine Ahnung, was ich bei IPv6 tun soll.
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();
Setzen Sie die obigen Anweisungen in try catch-Blöcke und wenn eine Ausnahme in catch bedeutet, dass keine Internetverbindung besteht. :-)
InetAddress.isReachable
gibt gelegentlich false zurück, wenn eine Internetverbindung besteht.
Eine alternative Methode zur Überprüfung der Internetverfügbarkeit in Java ist: Diese Funktion macht einen echten ICMP ECHO
-Ping aus.
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;
}
}
Ich zerlege es normalerweise in drei Schritte.
Wenn es zu irgendeinem Zeitpunkt fehlschlägt, sende ich dem Benutzer die entsprechende Fehlermeldung.
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;
}
Dieser Code ist in einer jUnit-Testklasse enthalten, mit der ich teste, ob eine Verbindung verfügbar ist. Ich erhalte immer eine Verbindung, aber wenn Sie die Länge des Inhalts überprüfen, sollte er -1 sein, falls er nicht bekannt ist:
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) Finden Sie heraus, wohin Ihre Anwendung eine Verbindung herstellen muss.
2) Richten Sie einen Arbeitsprozess ein, um InetAddress.isReachable zu überprüfen, um die Verbindung zu dieser Adresse zu überwachen.
Es gibt auch eine Gradle-Option --offline
, die möglicherweise zu dem gewünschten Verhalten führt.
Mit dem folgenden Code können wir den Status des Netzwerks auf unserem Android-Gerät abrufen
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");
}
}
}