We are developing some internal apps for mobile devices that are connected to internal wifis. We have some problems because we are only checking if the devices are connected using ConnectivityManager. But we need to check not only if there is connection, we need to check that the connection between the device and the server is working.
The problem is that ConnectivityManager tell us that the wifi is connected. But if the device is in an area with little coverage the app have errors trying to connect.
How can we easily check that the connection we have open against the server is still responding correctly? For example, one of the applications the connection is open against a SQL Server. Is there any way to check that we get to the server and it gives us an ok, and that we are not losing the connection and the packages because of the low coverage?
Thanks!!
You can try pinging the server if you receive a NullPointerException or IOException most likely there is no connection or connection timed out.
you can read more here an answer to similar question by syb0rg. Also remember to wrap this piece of code in an AsyncTask or a Thread to prevent your app from crashing.
try {
//replace URL with your domain
URL url = new URL("http://www.google.com");
HttpURLConnection urlConnect = (HttpURLConnection) url.openConnection();
urlConnect.setConnectTimeout(1000);
urlConnect.getContent();
System.out.println("Connection established.");
} catch (NullPointerException np) {
np.printStackTrace();
} catch (IOException io) {
io.printStackTrace();
}
Related
I'm noticing this for a while now, that often when my Wi-Fi is not working, my Android device is asking me to "Sign In" to that particular Wi-Fi network. It works flawlessly no matter which Wi-Fi network I'm connected to. Now I know that different ISPs have different Login pages and the url of all these pages are not the same. So, my question is, how does the Android OS find out the what's the url of the "Sign-In" page of the Wi-Fi network I'm connected to?
Any help regarding this query will be highly appreciated. Thank you for your time. :)
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
if (!url.getHost().equals(urlConnection.getURL().getHost())) {
// we were redirected! Kick the user out to the browser to sign on?
...
} finally {
urlConnection.disconnect();
}
}
Maybe you can find something here that does the work for you.
HTTP URL Connection
I'm having an intermittent connectivity issue with Android 4.1.2 and 4.2.2 whereby the HTTP stack seems to completely time-out (DNS Lookup and TCP/IP still works I can check that using ADB SHELL).
These connections are failing over GPRS, not over WiFi.
When checking netstat using SHELL I can see that the connections are sat waiting at SYN_SENT, and when inspecting the firewall on the server, we can see that it has responded to the SYN request but hasn't heard anything back from the device. During this outage it seems that all HTTP traffic fails on the device. Exchange no longer works and you cant request any pages using any of the common browsers (Firefox, Chrome), even though the device reports network and you can make / receive calls.
My application communicates over HTTP and HTTPS and during this outage both fail. POST and GET to my JSON web service, the requests hang and throw:
java.net.SocketTimeoutException: failed to connect to mywebaddress.com/1.1.1.1 (port 443) after 10000ms
This is expected if it's having trouble connecting as it is respecting the timeouts I have set below with the HttpURLConnection.
The code I use is as follows, located in an Async class. This is often contained in a connection loop, depending on how important the message is. This may be called up to 3 times with a 15 second gap in-between each call.
HttpURLConnection conn = null;
BufferedReader reader = null;
try
{
// Uses ConnectivityManager.getActiveNetworkInfo()
// Returns true, the Android OS reports a connection
if(myApp.hasNetworkConnection)
{
conn = (HttpURLConnection)endpoint.openConnection();
conn.setConnectTimeout(10000);
conn.setReadTimeout(20000);
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer strResults = new StringBuffer();
String strLine = "";
while ((strLine = reader.readLine()) != null)
{
strResults.append(strLine);
}
log(strResults.toString());
}
}
catch(Exception ex)
{
log(ex.getMessage());
}
finally
{
if(reader != null)
try
{
reader.Close();
reader = null;
}
catch(Exception ex)
{
ex.printStackTrace();
}
if(connection != null)
{
connection.disconnect();
connection = null;
}
}
I'm wondering if anyone has experienced this in the past, is the method of regularly trying the connection the wrong approach and exhausting the connection pool?
The connections that are created fire regularly and it doesn't (currently) batch connections together.
Just to share a bit more info, this is what netstat shows on the device (ADB Shell) when we experience the outage. The two "ESTABLISHED" connections are TCP connections not HTTP requests. The mobile has signal and the data symbol is showing a connection.
try this
try {
HttpURLConnection.setFollowRedirects(false);
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod("HEAD");
con.setConnectTimeout(5000); //set timeout to 5 seconds
return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
} catch (java.net.SocketTimeoutException e) {
return false;
} catch (java.io.IOException e) {
return false;
}
Just thought I would update, in-case this issue is experienced by anyone else.
The problem here is not with Android but the web service that the application is calling. Looking at it, when it was calling the JSON web service, it was taking far longer than expected (up to and over a minute) to return a response (if at all) and that response was always 200/OK.
As we were saturating the Android HTTP Stack with requests, eventually they were not clearing in a good enough time and would freeze up the device.
I added better fault tolerance to my code by setting the connect and read timeouts to more appropriate values rather than "0" (infinite) and we have looked at modifying the web service so that long running processes return a 201/Accepted status so that the device can carry on doing it's own work. We call the device back by other means (Google Cloud Message) once server processing has been completed.
I uploaded my app recently to Google Playstore. I used Error Reporter to track the crashes. App is working fine but very frequently I get HttpHostConnectException. Before making every web-call, I checked for Internet Connection. Are there any other reasons for the cause of this exception? How can it be avoided?
P.S. I never get this exception while testing/debugging my app.
HttpHostConnectException is thrown when connection cannot be established to a remote host on a specific port.
Before making every web-call, I checked for Internet Connection.
Checking internet connection is not a full-proof way to decide that the host is reachable. In many instances like using wifi, the device is connected to your router while the router is not connected to the internet. Checking internet connection using classes like ConnectivityManager in such cases returns true but the actual connection is false.
The solution is to check if your host is actually reachable using any http methods.
public boolean isInternetAvailable() {
try {
InetAddress ipAddr = InetAddress.getByName("google.com"); //You can replace it with your name
if (ipAddr.equals("")) {
return false;
} else {
return true;
}
} catch (Exception e) {
return false;
}
}
The above code is taken from this SO post.
I used AsyncHttpClient to handle all my webcalls. It handles my case perfectly. It directly takes to onFailure() on getting HttphostConnectException.
I've written a small file transfer program for android using standard Java sockets. The program works fine except for the following case:
I connect two android devices A and B over WiFi tethering connection. Device A is sharing the connection (enabled as wireless hotspot). When I run java server on A and client on B, the program works okay but when I run the server on device B, it can't accept any socket binding request from A. It doesn't throw any exception. Seems like the request is not reaching the server! However, both the devices are connected (ping test is okay in both directions). Can't I run socket server on a device connected as hotspot client? I thought once the networking is setup correctly, the application would work in any direction.
Also, Wireshark traces reveal nothing. What am I missing here? Please help! Here are my code snippets:
Server side (waiting for client connection):
while (true) {
try {
socket = serversocket.accept();
Runnable connectionHandler = new ConnectionHandler(
socket, fileArray, filepathNameArray,
SenderActivity.this, userID, handler);
new Thread(connectionHandler).start();
userID = userID + 1;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I would appreciate any kind of help! Thanks in advance.
I'm using this to upload some file. It works if I in a local connection, but if I use a external connection, i get this message: 425 Can't open data connection. from the ftp server.
I use the org.apache.commons.net.ftp.FTPClient and org.apache.commons.net.ftp.FTPFile libs.
public static String gravaImagem(String photoFile) {
FTPClient mFtp = new FTPClient();
try {
mFtp.connect(FTPHOST, PORTA);
mFtp.login(USUARIO, SENHA);
mFtp.setFileTransferMode(FTPClient.BINARY_FILE_TYPE);
mFtp.setFileType(FTPClient.BINARY_FILE_TYPE);
String origem = Environment.getExternalStorageDirectory().getPath()+File.separator+"Pictures"+File.separator+"ImageSec"+File.separator+photoFile;
FileInputStream fis = new FileInputStream(origem);
mFtp.storeFile(photoFile, fis);
mFtp.logout();
mFtp.disconnect();
} catch (SocketException e) {
e.printStackTrace();
return "Fail. (ERR#CON3)";
} catch (IOException e) {
e.printStackTrace();
return "Fail. (ERR#CON4)";
}
return "Imagem enviada ao servidor.";
}
Debug shows no exceptions.
From the internet:
First - the most common solution: change the active/passive mode
settings. But that might not work, and if it does its only a band-aid
covering up the real problem.
As I've mentioned in the past, one of the most common reasons that
this error occurs is a misconfiguration of the FTP server software
itself, related to SSL connections and firewalls, in which the
connection tries to establish itself on a bogus ip address. Read more
about FTP SSL through a NAT firewall here, some potential solutions
are included.
There are other less likely causes, such as:
The server is configured to always use the same port for passive mode connections, or the client is configured to always use the
same port for active mode connections, although in this case
usually the software in question should raise a different error
first, but I've seen this happen.
In passive mode, the firewall in front of the FTP server doesn't have the correct ports open. So the server tells the client to
connect to ipaddress 1.2.3.4 on port x, but the firewall doesn't
allow incoming connections on port x. Most firewalls are smart
enough to open up the port when it sees the PASV response. Vice
versa for active mode and the firewall in front of the FTP client.
From me:
I've used this library on andoird and it worked well, so see my copy/paste section.