Comment vérifier si vous pouvez vous connecter à Internet via Java? Une façon serait:
final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
... if we got here, we should have net ...
Mais y a-t-il quelque chose de plus approprié pour effectuer cette tâche, en particulier si vous devez effectuer des contrôles consécutifs très souvent et une perte de connexion Internet est hautement probable?
Vous devez vous connecter à l'endroit où votre application a réellement besoin. Sinon, vous testez si vous avez une connexion à un lieu non pertinent (Google dans ce cas).
En particulier, si vous essayez de parler à un service Web et que vous en contrôlez le service Web, il serait judicieux de recourir à une méthode Web peu coûteuse "obtenir l'état". De cette façon, vous avez une bien meilleure idée du potentiel de votre "vrai" appel.
Dans d'autres cas, le simple fait d'ouvrir une connexion à un port qui devrait être ouvert peut suffire - ou d'envoyer un ping. InetAddress.isReachable
est peut-être une API appropriée à vos besoins ici.
Le code que vous avez fourni, plus un appel à connect
devrait suffire. Donc oui, il se peut que Google ne soit pas disponible mais que vous deviez contacter un autre site, mais quelle est sa probabilité? En outre, ce code ne doit être exécuté que lorsque vous ne parvenez pas à accéder à votre ressource externe (dans un bloc catch
pour essayer de déterminer la cause de la défaillance). Je dirais donc que si votre ressource externe d’intérêt et Google ne sont pas disponibles Il est probable que vous rencontriez un problème de connectivité Internet.
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;
}
}
Des personnes ont suggéré d'utiliser INetAddress.isReachable. Le problème est que certains sites configurent leurs pare-feu pour bloquer les messages ICMP Ping. Donc, un "ping" peut échouer même si le service Web est accessible.
Et bien sûr, l'inverse est également vrai. Un hôte peut répondre à un ping même si le serveur Web est en panne.
Et bien sûr, une machine peut ne pas être en mesure de se connecter directement à certains (ou à tous) serveurs Web en raison des restrictions du pare-feu local.
Le problème fondamental est que "pouvoir se connecter à Internet" est une question mal définie, et ce genre de chose est difficile à tester sans:
En règle générale, la solution la plus simple consiste pour une application à essayer d'accéder à tout ce dont elle a besoin et à faire appel à l'intelligence humaine pour établir le diagnostic.
Si vous utilisez Java 6, vous pouvez utiliser NetworkInterface pour vérifier les interfaces réseau disponibles . I.e. quelque chose comme ça:
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface interf = interfaces.nextElement();
if (interf.isUp() && !interf.isLoopback())
return true;
}
Je n'ai pas encore essayé moi-même.
Ce code devrait faire le travail de manière fiable.
Notez que lorsque vous utilisez l'instruction try-with-resources
, il n'est pas nécessaire de fermer les ressources.
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;
}
}
}
Ce code:
"127.0.0.1".equals(InetAddress.getLocalHost().getHostAddress().toString());
Renvoie - pour moi - true
si hors ligne, et false
sinon. (bon, je ne sais pas si cela est vrai pour tous les ordinateurs).
Cela fonctionne beaucoup plus rapidement que les autres approches, ici.
EDIT: J'ai trouvé que cela ne fonctionne que si le "commutateur à bascule" (sur un ordinateur portable), ou une autre option définie par le système, pour la connexion Internet, est désactivée. En effet, le système lui-même sait qu'il ne faut rechercher aucune adresse IP.
Le code utilisant NetworkInterface pour attendre le réseau a fonctionné pour moi jusqu'à ce que je passe d'une adresse réseau fixe à un serveur DHCP. Une légère amélioration le fait aussi fonctionner avec 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;
}
}
}
Cela fonctionne pour Java 7 dans openSuse 13.1 pour le réseau IPv4. Le problème avec le code d'origine est que, même si l'interface était opérationnelle après la reprise de la suspension, une adresse réseau IPv4 n'était pas encore attribuée. Après avoir attendu cette affectation, le programme peut se connecter aux serveurs. Mais je ne sais pas quoi faire dans le cas d'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();
Mettez les déclarations ci-dessus dans des blocs catch try et si une exception est capturée, cela signifie qu'aucune connexion Internet n'est établie. :-)
InetAddress.isReachable
retourne parfois false s'il existe une connexion Internet.
Une autre méthode pour vérifier la disponibilité d'Internet en Java est la suivante: Cette fonction crée un vrai ping ICMP ECHO
.
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;
}
}
Je le décompose généralement en trois étapes.
Si cela échoue à tout moment, je fournis le message d'erreur approprié à l'utilisateur.
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;
}
Ce code est contenu dans une classe de test jUnit que j’utilise pour vérifier si une connexion est disponible. Je reçois toujours une connexion, mais si vous vérifiez la longueur du contenu, il devrait être -1 si vous ne le connaissez pas
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) Déterminez où votre application doit se connecter.
2) Configurez un processus de travail pour vérifier InetAddress.isReachable pour surveiller la connexion à cette adresse.
Il existe également une option de gradation --offline
qui peut entraîner le comportement souhaité.
Le code suivant nous permet d’obtenir l’état du réseau sur notre appareil 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");
}
}
}