Wifi connection works inspite of access point - android

I have a code that tests if a wifi connection is available.
public boolean checkInternetConnection() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
try {
URL url = new URL("http://www.google.com");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setRequestProperty("User-Agent", "Test");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(3000);
urlc.setReadTimeout(4000);
urlc.connect();
if (urlc.getResponseCode() == HttpURLConnection.HTTP_OK) {
Log.i(TAG,"Internet connection is OK");
return true;
}
} catch (MalformedURLException mue) {
mue.printStackTrace();
} catch (IOException ie) {
ie.printStackTrace();
}
}
Log.i(TAG, "No internet connection.");
return false;
}
To access the internet, I have to through an access point, this is why I espacially ping google because I need if we are also logged in. I have noticed that in many cases, eventhough I do not log into the captive portal, the code sill reaches google and returns true. I am also able to internet servers, such as ftp.
Does anyone know what is the cause of this behavior ? Has anyone else noticed this behavior ?
Thank you,

Some captive portals allow access without logging in to a limited set of services (e.g. company corporative website of the owner of the WiFi service). I've seen Google front page allowed in some WiFi APs I've used over the years. That may be what you've noticed.
Maybe a better approach (or additional) would be to check network detailed state NetworkInfo.html#getDetailedState() which also gives you information about captive portal detection.
Also, checking a specific page in your own servers may help (is less likely to be allowed without logging in), plus doing it through HTTPS instead of plain HTTP may give you additional information (is quite common to get a certificate not matching error because captive portals act like a man-in-the-middle).

Related

Can I detect programmatically if Android is connected to a wireless network but needs to sign in? [duplicate]

My university has an open wifi access point, however it requires you to enter your e-mail before it allows you to use the web. My problem is that the Wifi is stupid in that it seems to drop my connection and force me to enter my e-mail again every 10 minutes.
I wanted to create my own app that I can use to automatically do this step for me, but I cannot seem to find any documentation for a nice and easy way to detect if a Wifi access point has a browser login page. Is there a way in Android to get this information, or is it just to see if my connection to something is always redirected to 1.1.1.1?
See the "Handling Network Sign-On" section of the HttpUrlConnection documentation:
Some Wi-Fi networks block Internet access until the user clicks through a sign-on page. Such sign-on pages are typically presented by using HTTP redirects. You can use getURL() to test if your connection has been unexpectedly redirected. This check is not valid until after the response headers have been received, which you can trigger by calling getHeaderFields() or getInputStream().
They have a snippet of sample code there. Whether this will cover your particular WiFi AP, I can't say, but it is worth a shot.
Ping an external IP address (like google.com) to see if it responds.
try {
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("ping -c 1 " + "google.com");
proc.waitFor();
int exitCode = proc.exitValue();
if(exitCode == 0) {
Log.d("Ping", "Ping successful!";
} else {
Log.d("Ping", "Ping unsuccessful.");
}
}
catch (IOException e) {}
catch (InterruptedException e) {}
The only downside is this would also indicate that a web login is required when there is simply no internet connectivity on the WiFi access point.
#CommonsWare I believe this is a better answer than opening a UrlConnection and checking the host, since the host doesn't always change even when displaying the redirect page. For example, I tested on a Belkin router and it leaves whatever you typed in the browser as is, but still displays its own page. urlConnection.getUrl().getHost() returns what it should because of this.
I think #FlyWheel is on the right path, but I would use http://clients1.google.com/generate_204 and if you don't get a 204, you know you are behind a captive portal. You can run this in a loop until you do get a 204 in which case you know you are not behind a captive portal anymore.
#FlyWheel wrote: The only downside is this would also indicate that a web login is required when there is simply no internet connectivity on the WiFi access point.
You can solve this by registering a receiver to android.net.conn.CONNECTIVITY_CHANGE. You can check if Wifi is ON and is connected by looking at the Supplicant State of the connection.
Here is a snippet, but I didn't run it:
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wm.getConnectionInfo();
SupplicantState suppState = wifiInfo.getSupplicantState();
if (wm.isWifiEnabled()) {
if (suppState == SupplicantState.COMPLETED){
// TODO - while loop checking generate_204 (FlyWheels code)Using intent service.
}
}
I can't remember if the SupplicantState is COMPLETED or ASSOCIATED, you will have to check that. You should use an IntentService for checking the generate_204 since broadcast receivers have a short lifetime.
I used the following code using google's 204 endpoint.
private boolean networkAvailable() {
ConnectivityManager mManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if(mManager != null) {
NetworkInfo activeNetwork = mManager.getActiveNetworkInfo();
if(activeNetwork== null || !activeNetwork.isConnectedOrConnecting()){
return false;
}
}
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://clients1.google.com/generate_204")
.build();
try {
Response response = client.newCall(request).execute();
if(response.code() != 204)
return false; // meaning it either responded with a captive html page or did a redirection to captive portal.
return true;
} catch (IOException e) {
return true;
}
}
Many applications including Google Chrome use http://clients1.google.com/generate_204 to verify that the the connection is not locked under captive portal.
The issue might rather be - today at least - that newer Android versions (5.1+?) keep the 3G/4G connection up and running until the wifi login actually leads to a fully functional wifi connection.
I haven't tried it, but maybe with the enum value CAPTIVE_PORTAL_CHECK of NetworkInfos DetailedState one can try to detect such a mode properly?

Android is device connected to the internet method

I want to create a method which tells if the device is online. As far as I understand ConnectivityManager tells only if the device is connected to a network. This doesn't mean that the device is connected to the internet. To ensure that the device is online I'm using InetAddress.getByName("google.com").isReachable(3); but I can't use it on the main thread. I can create a separate thread to check the connectivity and then use a callback function but is there another way? I don't want my app to do anything before it is connected. Do you have any solutions? Thank you!
With any networking, there isn't a guaranteed way to check whether or not you are connected to an endpoint without actually sending data. Even if the device is connected to a network, has an ip address, recently received data, e.t.c, it doesn't mean that you still have a connection.
I would suggest allowing the user to progress into your application as much as possible, queuing up the requests to your server in the background whilst a connection is established. Use the same framework to resend data if the connection is lost whilst the user is using the app. Make the connection to the server as transparent to the user as possible, unless it fails to connect after ~1 minute
try this:
public static boolean isOnline(Context context) {
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
return true;
}
return false;
}

Access network availability state android

I am developing an application where i want to access whether there is internet connectivity or not. I can access the network state by using
private Boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
But this just returns whether the mobile is connected to internet or not. I want to know if there is internet availability after connecting. Like, may be the server is down or internet not available. Please let me know how to accomplish this!
To check that it's a working Internet connection and not just you are connected to Internet. You can do that by trying to fetch a known address/resource from your site, like a 1x1 PNG image or 1-byte text file. Also it will answer you about your server status. :)
Checking internet connection normally implemented, but if you want know your server working running or no, first you need send ping or send stub request(Example: send request with any params) to your server. If have response yes then you can work perfectly with your server.
Try like this,
URL url = new URL("Your URL");
URLConnection conexion = url.openConnection();
conexion.setConnectTimeout(10000); // Don't forget to put a time limit
conexion.connect();
After timeout (10 secs for above mentioned example), It will through time out exception.
So You can use it to check whether Internet access is available or not.

Android: HttpClient parameters - Connection and Socket Timeout

I could't find any helpful tutorials on internet nor the documentation on developers site.
In my application i am connecting to a Web Server using HttpPost, when there is no internet connection, but wifi is on it shows a white screen and after some 10-15 secs "UnknownHostException".
I caught this Exception and made toast like
Unable to connect, check your internet connection.
and close the Activity (or the Application, since i am using finish() on the 1st Activity).
When the wifi itself is off i get an instant toast like"
You need internet connection to use this Application
but the 1st case is irritating. Taking 10-15 secs time and then showing the toast.
So i used HttpParameters and added a 5 sec ConnectionTimeout parameter.
But the application works same as before(no effect of this parameters).
How can i track if i hit ConnectionTime(5 secs over). So that i can show a Toast like
Slow internet connection
moreover why is the internet connection check not working when wifi is on but no internet
this is what i check when my application is lauched:
cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (isOnline(cm, this, SignUpActivity.this)){
//continue
}
public static boolean isOnline(ConnectivityManager cm, Context c, Activity a) {
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
Toast.makeText(c, "You need internet access to run this application",
Toast.LENGTH_SHORT).show();
a.finish();
return false;
}
am i only checking whether device's wifi is on. if so, how can i check whether i have internet connection, instead of just wifi
Thank You
As for the first question, try using SocketTimeout instead.
As for the second question, the line
NetworkInfo netInfo = cm.getActiveNetworkInfo();
Will only get Wi-fi status (i.e. phone wifi antenna turned on) but not actual connectivity. The function returns immediately, so that if wifi is turned off you can toast out without checking connection further. But when wi-fi is turned on, you should go on and check your server's actual reachability, with something like
InetAddress.getByName(host).isReachable(timeOut)

how to mange wifi internet connectivity in android?

i use following code to check 3g,edge connectivity in android phone application
public boolean isConnected()
{
try
{
final ConnectivityManager conn_manager = (ConnectivityManager)
this.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo network_info = conn_manager.getActiveNetworkInfo();
if ( network_info != null && network_info.isConnected() )
{
return true;
}
else
{
return false;
}
}
catch (Exception e)
{
return false;
}
}
if i connect it to wifi then this check does not work correctly
actually when wifi is connected to network and internet coverage is not there above check say ok infact its wrong any one guide me how to handle packet lost case like
internet comming then disconnnecting and this process keeps continue in android ?
or am i doing something wrong?
any help would be appreciated.
if i connect it to wifi then this check does not work correctly
Yes, it does, by your own admission.
actually when wifi is connected to network and internet coverage is not there above check say ok
That is what it is supposed to do. Your WiFi network is active, meaning Android is in communication with your access point. That is what "connected" means.
The only way you can tell if you can communicate to some host is to try to communicate to some host. Note that requestRouteToHost() reportedly has issues, so you would need to try something else (e.g., make an HTTP connection to a known good URL).

Categories

Resources