How to test for active internet connection in android
Asked Answered
J

5

6

I'm using this method to ping google server so I can check for active internet connection but I discovered that it doesn't work on all devices.

I've tried using other methods like HttpURLConnection and URLConnection but they all return false even when i'm connected.

Any ideas or solutions one that works on all devices.Thanks in advance.I'll post in succession what I've tried already.

Method 1:

public static Boolean isOnline() {
    try {
        Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 8.8.8.8");
        int returnVal = p1.waitFor();
        return (returnVal == 0);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return false;
}

This one i've tried with locally and also with google servers and it yields perfect results.Problem is it doesn't work on all devices.

Method 2:

public boolean isConnected() {
    boolean connectivity;
    try {
        URL url = new URL("www.google.com");
        URLConnection conn = url.openConnection();
        conn.setConnectTimeout(5000);
        conn.connect();
        connectivity = true;
    } catch (Exception e) {
        connectivity = false;
    }
    return connectivity;
}

This one returns false always despite my connection being active.

Method 3:

public static boolean isInternetReachable() {
    try {
        //make a URL to a known source
        URL url = new URL("http://www.google.co.ke");

        //open a connection to that source
        HttpURLConnection urlConnect = (HttpURLConnection) url.openConnection();

        Object objData = urlConnect.getContent();

    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }

    return true;
}

Same as this one.False value.

The last one was this class but it's also doing the same thing:

class TestInternet extends AsyncTask<Void, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            URL url = new URL("http://www.google.com");
            HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
            urlc.setConnectTimeout(3000);
            urlc.connect();
            if (urlc.getResponseCode() == 200) {
                connected = true;
                return connected;
            }
        } catch (MalformedURLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
            connected = false;
            return connected;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            connected = false;
            return connected;
        }
        return connected;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        if (!result) { // code if not connected
            AlertDialog.Builder builder = new AlertDialog.Builder(CtgActivity.this);
            builder.setMessage("An internet connection is required.");
            builder.setCancelable(false);

            builder.setPositiveButton(
                    "TRY AGAIN",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            dialog.cancel();
                            new TestInternet().execute();
                        }
                    });


            AlertDialog alert11 = builder.create();
            alert11.show();
        } else { // code if connected
            Toast.makeText(CtgActivity.this,"Yes",Toast.LENGTH_LONG).show();
        }
    }

    @Override
    protected void onPreExecute() {
        Toast.makeText(getBaseContext(),"Checking for internet",Toast.LENGTH_LONG).show();
        super.onPreExecute();
    }
}

I was going through SO to find anything I could but everything revolves around these.Please tell me if it's something I'm doing wrong or suggest a better workaround for it.It's the last step in my project.

Jovial answered 2/3, 2018 at 5:58 Comment(0)
M
3

Follow below code to check properly Internet is available or not as well as active or not.

   //I have taken dummy icon from server, so it may be removed in future. So you can place one small icon on server and then access your own URL.

1. Specify Permission in manifest file, also make sure for marshmellwo runtime permission handle. As I am not going to show reuntime permission here.

    <uses-permission android:name="android.permission.INTERNET"/>

2. Check for Internet Availibility and the State as Active or Inactive.

        public class InternetDemo extends Activity
        {
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);

                checkInternetAvailibility();
            }

            public void checkInternetAvailibility()
            {
                if(isInternetAvailable())
                {
                    new IsInternetActive().execute();
                }
                else {
                    Toast.makeText(getApplicationContext(), "Internet Not Connected", Toast.LENGTH_LONG).show();
                }
            }

            public boolean isInternetAvailable() {
                try {
                    ConnectivityManager connectivityManager
                            = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
                    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
                } catch (Exception e) {

                    Log.e("isInternetAvailable:",e.toString());
                    return false;
                }
            }

            class IsInternetActive extends AsyncTask<Void, Void, String>
            {
                InputStream is = null;
                String json = "Fail";

                @Override
                protected String doInBackground(Void... params) {
                    try {
                        URL strUrl = new URL("http://icons.iconarchive.com/icons/designbolts/handstitch-social/24/Android-icon.png");
                        //Here I have taken one android small icon from server, you can put your own icon on server and access your URL, otherwise icon may removed from another server.

                        URLConnection connection = strUrl.openConnection();
                        connection.setDoOutput(true);
                        is =  connection.getInputStream();
                        json = "Success";

                    } catch (Exception e) {
                        e.printStackTrace();
                        json = "Fail";
                    }
                    return json;

                }

                @Override
                protected void onPostExecute(String result) {
                    if (result != null)
                    {
                       if(result.equals("Fail"))
                       {
                           Toast.makeText(getApplicationContext(), "Internet Not Active", Toast.LENGTH_LONG).show();
                       }
                       else
                       {
                           Toast.makeText(getApplicationContext(), "Internet Active " + result, Toast.LENGTH_LONG).show();
                       }
                    }
                    else
                    {
                        Toast.makeText(getApplicationContext(), "Internet Not Active", Toast.LENGTH_LONG).show();
                    }
                }

                @Override
                protected void onPreExecute() {
                    Toast.makeText(getBaseContext(),"Validating Internet",Toast.LENGTH_LONG).show();
                    super.onPreExecute();
                }
            }
        }
Marder answered 2/3, 2018 at 7:30 Comment(5)
You sir are the real mvp.It works perfectly as i wanted.Jovial
most certainly.Just one thing,when its connected but no data,it takes a long time to verify,how can i reduce the response time?If possibleJovial
That I mentioned in code, you need to put your own very small image or might be send some text in URL so it will reduce response time and you can easily get response.Marder
I have tested this txt file also, "w3.org/TR/PNG/iso_8859-1.txt" but this is also too much long text so use youer own like hello world or welcome or success whatever small messageMarder
Why am I getting FileNotFoundException?Homesteader
J
1

Step 1 : Create connection detector

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

import java.net.HttpURLConnection;
import java.net.URL;


    /**
     * Created by Ramana Tech Architect 2/24/2018.
     */

    public class ConnectionDetector {

    private Context _context;

    public ConnectionDetector(Context context) {
        this._context = context;
    }

    public boolean isConnectingToInternet() {
        ConnectivityManager cm = (ConnectivityManager) this._context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (activeNetwork != null) { // connected to the internet
                try {
                    URL url = new URL("http://www.google.com");
                    HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
                    urlc.setConnectTimeout(300);
                    urlc.connect();
                    if (urlc.getResponseCode() == 200) {
                        return true;
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    return false;
                }
        }
        return false;
    }
}

Step 2: Use ConnectionDetector

private ConnectionDetector cd;

        cd = new ConnectionDetector(getApplicationContext());

        if (cd.isConnectingToInternet()) {
             /// block of code 
          }

Tested Output : enter image description here

I connected with wifi and mobile so output is true in log 2 times. I disconnected the wifi so false in 3rd line

Jovitta answered 2/3, 2018 at 6:5 Comment(13)
let me try it right now and get back to you.Hope it worksJovial
wait.Im not checking if network is connected.Im checking whether the connection is active or not.Jovial
I hope you got exact solutionJovitta
No, I tested itJovitta
I've tried it but it's returning false also.I tried increasing the timeout to three seconds and the response time to two but still its returning falseJovial
still didn't work.tried even introducing another variable(boolean) but it returns false yet im connected.Please run my first method on your device to seeJovial
yes,even <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> is thereJovial
I'm sure. It might be the issue with the device/internet only. try to print the response in log of urlc so that you will know exact issueJovitta
are you trying with real device?Jovitta
yes...and the answer i upvoted works perfectly>yours seems like it can work I just dont know what im not doing.Jovial
you can up vote if you feel the answer is correct and it would be helpful for other guys who trying to do the same.Jovitta
I guess, it is other issue so if you share more about the logic then I can help youJovitta
I think i found the issue with this.Let me confirm it though.But be checking also,see the accepted answer uses an image,your method and others i tried all use google server.I tried using google server with accepted answer and it gave false.maybe google doesnt want to be pinged maybe in my country I guessJovial
G
0

Create a ProjectUtils Class on your package :

Don't forget to add in your Menifests

<uses-permission android:name="android.permission.INTERNET" />

ProjectUtils.java :

public class ProjectUtils {

    Context context;

    public ProjectUtils(Context context) {
        this.context = context;
    }



    public boolean haveNetworkConnection() {

        boolean haveConnectedWifi = false;
        boolean haveConnectedMobile = false;

        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo[] netInfo = cm.getAllNetworkInfo();
        for (NetworkInfo ni : netInfo) {
            if (ni.getTypeName().equalsIgnoreCase("WIFI"))
                if (ni.isConnected())
                    haveConnectedWifi = true;
            if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
                if (ni.isConnected())
                    haveConnectedMobile = true;
        }
        return haveConnectedWifi || haveConnectedMobile;
    }

    public void showtoast(String text) {
        Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
    }

}

Inside your Activity :

  ProjectUtils utils;

     @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        utils = new ProjectUtils(this);

             if (utils.haveNetworkConnection()) {
                   jsonRequestCall();
                } else {
                     utils.showtoast("Internet Connection Not Available");
                }

    }

If you want to check Internet Connection Every-time within Seconds Then you have to go with BroadcastReceiver .

Reference :

Gabelle answered 2/3, 2018 at 6:18 Comment(7)
This one checks whether the phone is connected to network.What i want is to check whether the connected network is working.Like can i communicate with a server?Thats what I want.One thing though,whats jsonRequestCall method?Jovial
jsonRequestCall(); is just a method call you can also show Toast over there , When this Activity launches first my code checks the internet , if internet available it will call method otherwise shows toast that "Internet is not available" @ThekambleGabelle
Then this is not what I was aiming for.See sometimes you're connected to a network but you have loaded data so can't communicate with servers.Thats what I wanted to check onJovial
Do you want to check everyTime internet connect like Todays Messanger apps @ThekambleGabelle
Yes,but for my case not necessarily all the time.just a one time check like the app in this link: apk4fun.com/link/77870/a/.A one time check so I can decide based on that which layout to load.Jovial
Then go with my code , sure it will work for you @ThekambleGabelle
you didn't understand me.Please run my first code on your device.Hopefully it works on yours and try connecting to internet.Youll see that if youre connected but dont have data,itll give false value.thats what I wantJovial
D
0

Didn't tryed this too but I found this:

public static boolean isInternetAvailable() {
    Boolean isConnection = false;
    int connectTimeout = 5000; // in ms
    int readTimeout = 5000; // in ms
    String ip204 = "http://clients3.google.com/generate_204";

    try {
        URL url = new URL(ip204);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(connectTimeout);
        conn.setReadTimeout(readTimeout);
        conn.setRequestMethod("HEAD");
        InputStream in = conn.getInputStream();
        int status = conn.getResponseCode();
        in.close();
        conn.disconnect();
        if (status == HttpURLConnection.HTTP_NO_CONTENT) {
            isConnection = true;
        }
    } catch (Exception e) {
        isConnection = false;
    }
}

but this method must be inside a thread different to the Main Thread so it is async :/

I didn't tryed this but I found this code online that use a NetworkCallback:

private void listenNetworkViaConnectivityManager(final Context context) {
  ConnectivityManager cm = (ConnectivityManager) context
      .getSystemService(Context.CONNECTIVITY_SERVICE);
  NetworkRequest request = new NetworkRequest.Builder()
      .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
      .build();
  cm.registerNetworkCallback(request, new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
      // do what you want
    }
  });
}

but probably is the same as ConnectivityManager... and also it uses a callback so is asynchronous and cannot return sync value true/false I think :/ Maybe, if this works as you want, you can check for connection every tot time using a service o something like a service and then set a flag variable, a static global variable to true if there is internet connection and to false if there isn't. To check if there is or there's not you will just check this flag.

I didn't tryed it and I think it's a really bad method but I don't have found any other solution so... maybe you can use an SNTP Client instead of the ping fuction (setting the timeout to a really little value obviously).

public static Date getCurrentDateFromSNTP() {
        try {
            SntpClient client = new SntpClient();
            if (client.requestTime(SntpClient.NTP_SERVER, SntpClient.NTP_TIMEOUT)) {
                long now = client.getNtpTime() + SystemClock.elapsedRealtime() - client.getNtpTimeReference();
                return new Date(now);
            }
        } catch (Exception e) {
            EMaxLogger.onException(TAG, e);
        }
        return new Date();
    }

/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.emax.it.lib_commons.modules.networking.clients;

import android.os.AsyncTask;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;

import com.emax.it.lib_commons.modules.loggers.EMaxLogger;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.concurrent.ExecutionException;

/**
 * {@hide}
 *
 * Simple SNTP client class for retrieving network time.
 *
 * Sample usage:
 * <pre>SntpClient client = new SntpClient();
 * if (client.requestTime("time.foo.com")) {
 *     long now = client.getNtpTime() + SystemClock.elapsedRealtime() -
 * client.getNtpTimeReference();
 * }
 * </pre>
 */
public class SntpClient {

    private static final String TAG = SntpClient.class.getSimpleName();
    // Ntp
    public static final String NTP_SERVER = "time.google.com";
    public static final int NTP_TIMEOUT = 2 * 1000; // 2 secondi il timeout
    // Time Offset Data
    private static final int REFERENCE_TIME_OFFSET = 16;
    private static final int ORIGINATE_TIME_OFFSET = 24;
    private static final int RECEIVE_TIME_OFFSET = 32;
    private static final int TRANSMIT_TIME_OFFSET = 40;
    // NTP Data
    private static final int NTP_PACKET_SIZE = 48;
    private static final int NTP_PORT = 123;
    private static final int NTP_MODE_CLIENT = 3;
    private static final int NTP_VERSION = 3;
    // Number of seconds between Jan 1, 1900 and Jan 1, 1970
    // 70 years plus 17 leap days
    private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;
    // system time computed from NTP server response
    private long mNtpTime;
    // value of SystemClock.elapsedRealtime() corresponding to mNtpTime
    private long mNtpTimeReference;
    // round trip time in milliseconds
    private long mRoundTripTime;

    /**
     * Returns the time computed from the NTP transaction.
     *
     * @return time value computed from NTP server response.
     */
    public long getNtpTime() {
        return mNtpTime;
    }

    public void setNtpTime(long ntpTime){
        mNtpTime = ntpTime;
    }

    /**
     * Returns the reference clock value (value of SystemClock.elapsedRealtime())
     * corresponding to the NTP time.
     *
     * @return reference clock corresponding to the NTP time.
     */
    public long getNtpTimeReference() {
        return mNtpTimeReference;
    }

    public void setNtpTimeReference(long ntpTimeReference){
        mNtpTimeReference = ntpTimeReference;
    }

    /**
     * Returns the round trip time of the NTP transaction
     *
     * @return round trip time in milliseconds.
     */
    public long getRoundTripTime() {
        return mRoundTripTime;
    }

    public void setRoundTripTime(long roundTripTime){
        mRoundTripTime = roundTripTime;
    }

    /**
     * Sends an SNTP request to the given host and processes the response.
     *
     * @param host    host name of the server.
     * @param timeout network timeout in milliseconds.
     * @return true if the transaction was successful.
     */
    public boolean requestTime(String host, int timeout) {
        try {
            return new RequestTimeTask(this, host, timeout).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR).get();
        } catch (InterruptedException iE) {
            EMaxLogger.onException(TAG, iE);
        } catch (ExecutionException eE) {
            EMaxLogger.onException(TAG, eE);
        }
        return false;
    }

    /**
     * Reads an unsigned 32 bit big endian number from the given offset in the buffer.
     */
    private long read32(byte[] buffer, int offset) {
        byte b0 = buffer[offset];
        byte b1 = buffer[offset + 1];
        byte b2 = buffer[offset + 2];
        byte b3 = buffer[offset + 3];

        // convert signed bytes to unsigned values
        int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0);
        int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1);
        int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2);
        int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3);

        return ((long) i0 << 24) + ((long) i1 << 16) + ((long) i2 << 8) + (long) i3;
    }

    /**
     * Reads the NTP time stamp at the given offset in the buffer and returns
     * it as a system time (milliseconds since January 1, 1970).
     */
    private long readTimeStamp(byte[] buffer, int offset) {
        long seconds = read32(buffer, offset);
        long fraction = read32(buffer, offset + 4);
        return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L) / 0x100000000L);
    }

    /**
     * Writes system time (milliseconds since January 1, 1970) as an NTP time stamp
     * at the given offset in the buffer.
     */
    private void writeTimeStamp(byte[] buffer, int offset, long time) {
        long seconds = time / 1000L;
        long milliseconds = time - seconds * 1000L;
        seconds += OFFSET_1900_TO_1970;

        // write seconds in big endian format
        buffer[offset++] = (byte) (seconds >> 24);
        buffer[offset++] = (byte) (seconds >> 16);
        buffer[offset++] = (byte) (seconds >> 8);
        buffer[offset++] = (byte) (seconds >> 0);

        long fraction = milliseconds * 0x100000000L / 1000L;
        // write fraction in big endian format
        buffer[offset++] = (byte) (fraction >> 24);
        buffer[offset++] = (byte) (fraction >> 16);
        buffer[offset++] = (byte) (fraction >> 8);
        // low order bits should be random data
        buffer[offset++] = (byte) (Math.random() * 255.0);
    }

    /** Private Classes **/
    private static class RequestTimeTask extends AsyncTask<Void, Void, Boolean> {

        private SntpClient mOuter;
        private String mHost;
        private int mTimeout;

        RequestTimeTask(SntpClient outer, String host, int timeout){
            mOuter = outer;
            mHost = host;
            mTimeout = timeout;
        }

        /** Override AsyncTask Methods **/
        @Override
        protected Boolean doInBackground(Void... voids) {
            try (DatagramSocket socket = new DatagramSocket()) {
                socket.setSoTimeout(mTimeout);
                InetAddress address = InetAddress.getByName(mHost);
                byte[] buffer = new byte[NTP_PACKET_SIZE];
                DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);

                // set mode = 3 (client) and version = 3
                // mode is in low 3 bits of first byte
                // version is in bits 3-5 of first byte
                buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);

                // get current time and write it to the request packet
                long requestTime = System.currentTimeMillis();
                long requestTicks = SystemClock.elapsedRealtime();
                mOuter.writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET, requestTime);

                socket.send(request);

                // read the response
                DatagramPacket response = new DatagramPacket(buffer, buffer.length);
                socket.receive(response);
                long responseTicks = SystemClock.elapsedRealtime();
                long responseTime = requestTime + (responseTicks - requestTicks);

                // extract the results
                long originateTime = mOuter.readTimeStamp(buffer, ORIGINATE_TIME_OFFSET);
                long receiveTime = mOuter.readTimeStamp(buffer, RECEIVE_TIME_OFFSET);
                long transmitTime = mOuter.readTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
                long roundTripTime = responseTicks - requestTicks - (transmitTime - receiveTime);
                // receiveTime = originateTime + transit + skew
                // responseTime = transmitTime + transit - skew
                // clockOffset = ((receiveTime - originateTime) + (transmitTime - responseTime))/2
                //             = ((originateTime + transit + skew - originateTime) +
                //                (transmitTime - (transmitTime + transit - skew)))/2
                //             = ((transit + skew) + (transmitTime - transmitTime - transit + skew))/2
                //             = (transit + skew - transit + skew)/2
                //             = (2 * skew)/2 = skew
                long clockOffset = ((receiveTime - originateTime) + (transmitTime - responseTime)) / 2;
                // if (false) Log.d(TAG, "round trip: " + roundTripTime + " ms");
                // if (false) Log.d(TAG, "clock offset: " + clockOffset + " ms");

                // save our results - use the times on this side of the network latency
                // (response rather than request time)
                mOuter.setNtpTime(responseTime + clockOffset);
                mOuter.setNtpTimeReference(responseTicks);
                mOuter.setRoundTripTime(roundTripTime);
                return true;
            } catch (Exception e) {
                if(TextUtils.isEmpty(e.getMessage())){
                    Log.e(TAG, String.format("No Message for %1$s", e.getClass().getSimpleName()));
                } else {
                    Log.e(TAG, e.getMessage());
                }
                e.printStackTrace();
                return false;
            }
        }

    }

}
Designate answered 10/5, 2022 at 13:50 Comment(0)
H
0

I used this super easy library. It is fast and reliable.

https://github.com/JobGetabu/DroidNet

Homesteader answered 28/9, 2022 at 6:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.