According to the Android developer site, Determining and Monitoring the Connectivity Status, we can check there is an active Internet connection. But this is not working if even only Wi-Fi is connected and not Internet available (it notifies there is an Internet connection).
Now I ping a website and check whether Internet connections are available or not. And this method needs some more processing time. Is there a better method for checking Internet connectivity than this to avoid the time delay in ping the address?
Try this:
It's really simple and fast:
public boolean isInternetAvailable(String address, int port, int timeoutMs) {
try {
Socket sock = new Socket();
SocketAddress sockaddr = new InetSocketAddress(address, port);
sock.connect(sockaddr, timeoutMs); // This will block no more than timeoutMs
sock.close();
return true;
} catch (IOException e) { return false; }
}
Then wherever you want to check just use this:
if (isInternetAvailable("8.8.8.8", 53, 1000)) {
// Internet available, do something
} else {
// Internet not available
}
The first problem you should make it clear is what do you mean by whether internet is available?
Not connected to wifi or cellular network;
Connected to a limited wifi: e.g. In a school network, if you connect to school wifi, you can access intranet directly. But you have to log in with school account to access extranet. In this case, if you ping extranet website, you may receive response because some intranet made auto redirect to login page;
Connected to unlimited wifi: you are free to access most websites;
The second problem is what do you want to achieve?
As far as I understand your description, you seems want to test the connection of network and remind user if it fails. So I recommend you just ping your server, which is always fine if you want to exchange data with it.
You wonder whether there is a better way to test connectivity, and the answer is no.
The current TCP/IP network is virtual circuit, packet-switched network, which means there is no a fixed 'path' for the data to run, i.e. not like a telephone, we have a real connection between two users, we can know the connection is lost immediately after circuit is broken. We have to send a packet to the destination, and find no response, then we know, we lose the connection (which is what ping -- ICMP protocol -- does).
In conclusion, we have no better way to test the connectivity to a host other than ping it, that is why heartbeat is used in service management.
Try the following:
public boolean checkOnlineState() {
ConnectivityManager CManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo NInfo = CManager.getActiveNetworkInfo();
if (NInfo != null && NInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
Don't forget the access:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Else:
if (InetAddress.getByName("www.google.com").isReachable(timeout))
{ }
else
{ }
On checking this issue it found that We cannot determine whether an active internet connection is there, by using the method specified in the developer site:
https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html
This will only check whther ther active connection of wifi.
So I found 2 methods which will check whether there is an active internet connection
1.Ping a website using below method
URL url = new URL(myUrl);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
// 30 second time out.
httpURLConnection.setConnectTimeout(30000);
httpURLConnection.connect();
if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
isAvailable = true;
}
2.Check the availability of Google DNS using socket
try {
Socket sock = new Socket();
SocketAddress sockaddr = new InetSocketAddress("8.8.8.8", 53);
sock.connect(sockaddr, 1000); // this will block no more than timeoutMs
sock.close();
return true;
}
The second method is little faster than 2nd method (Which suits for my requirement)
Thanks all for the answers and support.
I wanted to comment, but not enough reputation :/
Anyways, an issue with the accepted answer is it doesn't catch a SocketTimeoutException, which I've seen in the wild (Android) that causes crashes.
public boolean isInternetAvailable(String address, int port, int timeoutMs) {
try {
Socket sock = new Socket();
SocketAddress sockaddr = new InetSocketAddress(address, port);
sock.connect(sockaddr, timeoutMs); // This will block no more than timeoutMs
sock.close();
return true;
} catch (IOException e) {
return false;
} catch (SocketTimeoutException e) {
return false;
}
}
//***To verify internet access
public static Boolean isOnline(){
boolean isAvailable = false;
try {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
URL url = new URL("https://stackoverflow.com/");
HttpURLConnection httpURLConnection = null;
httpURLConnection = (HttpURLConnection) url.openConnection();
// 2 second time out.
httpURLConnection.setConnectTimeout(2000);
httpURLConnection.connect();
if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
isAvailable = true;
} else {
isAvailable = false;
}
} catch (IOException e) {
e.printStackTrace();
isAvailable = false;
}
if (isAvailable){
return true;
}else {
return false;
}
}
ConnectivityManager will not be able to tell you if you have active connection on WIFI.
The only option to check if we have active Internet connection is to ping the URL. But you don't need to do that with every HTTP request you made from your App.
What you can do:
Use below code to check connectivity
private boolean checkInternetConnection()
{
ConnectivityManager cm = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
// test for connection
if (cm.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().isAvailable()
&& cm.getActiveNetworkInfo().isConnected())
{
return true;
}
else
{
return false;
}
}
And while making rest call using HTTP client set timeout like 10 seconds. If you don't get response in 10 seconds means you donot have active internet connection and exception will be thrown (Mostly you get response within 10 seconds). No need to check active connection by pinging everytime (if you are not making Chat or VOIP app)
Maybe this can help you:
private boolean checkInternetConnection() {
ConnectivityManager cm = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
// Test for connection
if (cm.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().isAvailable()
&& cm.getActiveNetworkInfo().isConnected()) {
return true;
}
else {
return false;
}
}
Try this method, this will help you:
public static boolean isNetworkConnected(Context context)
{
ConnectivityManager connectivityManager = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null)
{
NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected())
{
return true;
}
}
return false;
}
You can try this for check Internet connectivity:
/**
* Check Connectivity of network.
*/
public static boolean isOnline(Context context) {
try {
if (context == null)
return false;
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm != null) {
if (cm.getActiveNetworkInfo() != null) {
return cm.getActiveNetworkInfo().isConnected();
} else {
return false;
}
} else {
return false;
}
}
catch (Exception e) {
Log.error("Exception", e);
return false;
}
}
In your activity you call this function like this.
if(YourClass.isOnline(context))
{
// Do your stuff here.
}
else
{
// Show alert, no Internet connection.
}
Don't forget to add ACCESS_NETWORK_STATE PERMISSION:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Try this if you want to just ping the URL:
public static boolean isPingAvailable(String myUrl) {
boolean isAvailable = false;
try {
URL url = new URL(myUrl);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
// 30 second time out.
httpURLConnection.setConnectTimeout(30000);
httpURLConnection.connect();
if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
isAvailable = true;
}
} catch (Exception e) {
isAvailable = false;
e.printStackTrace();
}
return isAvailable;
}
Related
This code works:
public static boolean isConnected()
{
ConnectivityManager cm = (ConnectivityManager)App.getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni != null) {
if (ni.getType() == ConnectivityManager.TYPE_WIFI)
if (ni.isConnected())
return true;
if (ni.getType() == ConnectivityManager.TYPE_MOBILE)
if (ni.isConnected())
return true;
if (ni.getType() == ConnectivityManager.TYPE_ETHERNET)
if (ni.isConnected())
return true;
}
return false; //none of connections available
}
The question is: do we also have to check TYPE_MOBILE_DUN, TYPE_WIMAX and TYPE_VPN?
Can a device be connected to the Internet over Bluetooth?
Just one comment. Think what do you need and remember to be connected to a wifi router doesn't mean you have internet connection or that you are able to reach any point of interest like a backend server.
If your app needs to access a service to work, may be the best way it is to check if you can reach it in an early stage through an async call and only proceed if you could validate that connection.
Try to make a simple GET request to http://www.google.com. If your response code is 200 or 400 Then the internet connection exists.
protected static boolean hasInternetAccess()
{
try
{
URL url = new URL("http://www.google.com");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setRequestProperty("User-Agent", "Android Application:1");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(1000 * 30);
urlc.connect();
// http://www.w3.org/Protocols/HTTP/HTRESP.html
if (urlc.getResponseCode() == 200 || urlc.getResponseCode() > 400)
{
// Requested site is available
return true;
}
}
catch (Exception ex)
{
// Error while trying to connect
return false;
}
return false;
}
For more info, refer to: The perfect function to check Android internet connectivity including bluetooth pan
This is all I use:
public static boolean isOffline() {
ConnectivityManager cm = (ConnectivityManager) BigOvenApplication.getInstance()
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo == null || !netInfo.isConnected();
}
I don't think you need anything more than that.
Just call the method isConnectedToNetwork to check whether it has connection or not. Write this method in a common class file. Thereby you can use simple methodcall where ever you need.
public static boolean isConnectedToNetwork(Context thisActivity) {
ConnectivityManager connMgr = (ConnectivityManager) thisActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeInfo = connMgr.getActiveNetworkInfo();
if (activeInfo != null && activeInfo.isConnected()) {
return true;
}
return false;
}
Check before you start the operation.
//thisActivity means getActivity() for fragments
if (isConnectedToNetwork(thisActivity)) {
// your operation code follows
} else {
//show alert box that there is no internet connection
}
Typically when building my android applications that require API calls etc, I check the NetworkAvailability before making such calls like so:
public boolean networkIsAvailable() {
boolean result = false;
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager
.getActiveNetworkInfo();
if (activeNetworkInfo != null) {
if (activeNetworkInfo.isConnected()) {
result = true;
}
}
return result;
}
Simple enough... But what happens when say a user is on a device that has no Mobile Connection and is connected to a Wifi Network, but that Wifi Network doesn't have internet access.
Are there options aside from catching a java.net.UnknownHostException to test for actual internet access?
You can use this:
public static boolean hasActiveInternetConnection(Context context) {
if (isNetworkAvailable(context)) {
try {
HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection());
urlc.setRequestProperty("User-Agent", "Test");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(1500);
urlc.connect();
return (urlc.getResponseCode() == 200);
} catch (IOException e) {
Log.e(LOG_TAG, "Error checking internet connection", e);
}
} else {
Log.d(LOG_TAG, "No network available!");
}
return false;
}
Remember this: "As Tony Cho also pointed out in this comment below, make sure you don't run this code on the main thread, otherwise you'll get a NetworkOnMainThread exception (in Android 3.0 or later). Use an AsyncTask or Runnable instead."
Source: Detect if Android device has Internet connection
I have built an android application that requires continuous internet access. I want to check it continuously, not only if the device is connected to a WiFi but also that it can retrieve data (sometimes it is connected to WiFi but still has no internet access). Is there an approach to achieve this? Also will this approach be friendly for the user (will it eat up more data) ?
you can use this.
public boolean isConnected() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
isConnected used for checking connection to network, then use following code to check Internet accessibility
public boolean isOnline() {
if (isConnected()) {
try {
URL url = new URL("http://www.google.com"); // or any valid link.
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(3000);
urlc.connect();
if (urlc.getResponseCode() == 200) {
return true;
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return false;
}
you can call this from server class
I want to check it continuously, not only if the device is connected
to a WiFi but also that it can retrieve data (sometimes it is
connected to WiFi but still has no internet access). Is there an
approach to achieve this?
Yes, it's possible. Code from here:
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
You can run this before making network requests.
Alternatively you can implement a BoadcastReceiver and be notified on network connection changes. You need to register for the action:
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
More info in the developer guide.
I am checking the network status of a device. using:-
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
I want to take this on a little further and check to see if the device can access the internet or a given site such as http://www.google.com and if it can then return as true and if it can't then return as false.
The problem with my code is that it will return true if the device is connected to a router and the router is offline. I need an actual internet connection check.
Amended code
public void GoToStation(View v)
{
try {
InetAddress ina = InetAddress.getByName("http://188.65.176.98/");
if(ina.isReachable(3000)) {
Intent myIntent = new Intent(MainActivity.this, CustomizedListViewStation.class);
startActivityForResult(myIntent, 0);
} else {
Toast.makeText(this, "You need a data connection to view Safety Zones", Toast.LENGTH_LONG).show();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
You could do something like this:
boolean isAvailable(URL url){
try {
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
urlConnection.disconnect();
return true;
} catch (IOException e) {
Log.e(TAG, "Exception", e);
}
return false;
}
To check for an actual internet connection, you could try to access some remote server. For example:
try {
InetAddress ina = InetAddress.getByName([server]);
if(ina.isReachable(3000)) {
System.out.println("Internet Connection");
} else {
System.out.println("No internet connection");
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
Where [server] is the server to try to connect to. You should use your own server for this since it's rude to use someone else's bandwidth for this purpose (plus using your own server is more reliable).
Another route is to check if there's an Android API that does this since Android checks for a connection to Google's servers. I'm not sure if this status is exposed in the API anywhere though.
Today I found a strange thing while testing my application in android device. In My Device I have enable the WIFI connection, but due to some internal problem internet connectivity is not available, and my application was not executed and after restarting the device it works fine. So how to handle this situation.
[In my application I have validate WIFI and Mobile Network]
I had a weird problem on the network in work. I would connect phone to our network over wifi and it would connect to the network grand and the status would be "Connected to name of network". But after about 10 minutes off my phone being connected to Wifi. When I check the phone status it says "authenticating with [name of network].
This problem resulted in a while of debugging as even when it says it is "authenticating" I could still access my gmail/facebook and websites on my phone. However when I tried my connect method similar to scorpio it would return not connected to internet.
Here is mine:
/**
* Method to see if device has any access to the Internet.
* #return boolean true if connected, otherwise false.
*/
public boolean isConnectedToInternet()
{
try{
ConnectivityManager cm = (ConnectivityManager) getSystemService
(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected())
{
//Network is available but check if we can get access from the network.
URL url = new URL("http://www.Google.com/");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(2000); // Timeout 2 seconds.
urlc.connect();
if (urlc.getResponseCode() == 200) //Successful response.
{
return true;
}
else
{
Toast.makeText(this, "No connection to internet.", Toast.LENGTH_LONG).show();
Log.d("NO INTERNET", "NO INTERNET");
return false;
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
Toast.makeText(this, "No connection to internet.", Toast.LENGTH_LONG).show();
return false;
}
However when the phone saids its authenticating this line here would return null.
NetworkInfo netInfo = cm.getActiveNetworkInfo();
So like I said when authenicating I could still access web on phone and apps such as facebook/gmail still worked but apps such as mine or some of my colleagues who used a similar approach above didn't.
Which obviously I can see why when I figured out why this was the case. Just got me curious to how are the apps such as facebook/gmail testing a connection to the internet.
So I was wondering should I just take a simple approach of doing this:
URL url = new URL("http://www.Google.com/");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(2000); // Timeout 2 seconds.
urlc.connect();
if (urlc.getResponseCode() == 200) //Successful response.
{
return true;
}
else
{
Toast.makeText(this, "No connection to internet.", Toast.LENGTH_LONG).show();
Log.d("NO INTERNET", "NO INTERNET");
return false;
}
Anyway the question posted is rather vague so hard to say what the internal problem you speak off is and how to fix it. Just seemed similar to a fustration.
Try this,
protected boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
return true;
} else {
return false;
}
}
OR
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo().isConnectedOrConnecting();
}