如何在 android 中测试活动互联网连接

How to test for active internet connection in android

我正在使用此方法 ping google 服务器,以便检查活动的 internet 连接,但我发现它不适用于所有设备。

我试过使用其他方法,如 HttpURLConnectionURLConnection,但即使我已连接,它们都 return 错误。

任何适用于 advance.I 中所有 devices.Thanks 的想法或解决方案都会 post 继承我已经尝试过的方法。

方法一:

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;
}

这个我已经在本地和 google 服务器上试过了,它产生了完美的效果 results.Problem 是它不适用于所有设备。

方法二:

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;
}

尽管我的连接处于活动状态,但这个 return 总是错误的。

方法三:

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;
}

与此 one.False 值相同

最后一个是这个 class 但它也在做同样的事情:

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();
    }
}

我正在通过 SO 寻找任何我能找到的东西,但一切都围绕 these.Please 展开在我的项目中。

步骤 1: 创建连接检测器

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;
    }
}

步骤 2:使用 ConnectionDetector

private ConnectionDetector cd;

        cd = new ConnectionDetector(getApplicationContext());

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

测试输出:

我连接了 wifi 和移动设备,所以在日志中有 2 次输出为真。 我在第 3 行断开了 wifi 的连接

在您的包裹上创建一个 ProjectUtils Class :

别忘了添加您的 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();
    }

}

在你的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");
                }

    }

如果你想在几秒钟内检查 Internet 连接 Every-time 那么你必须使用 BroadcastReceiver .

参考:

按照下面的代码来正确检查 Internet 是否可用以及是否处于活动状态。

   //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.在清单文件中指定权限,同时确保 marshmellwo 运行时权限句柄。因为我不打算在这里显示重新运行时间许可。

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

2。检查 Internet 可用性和状态为活动或非活动。

        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();
                }
            }
        }

没试过,但我发现了这个:

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;
    }
}

但是这个方法必须在不同于主线程的线程中,所以它是异步的:/

我没试过,但我在网上找到了这段使用 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
    }
  });
}

但可能与 ConnectivityManager 相同...而且它使用回调,因此是异步的并且不能 return 同步值 true/false 我认为:/ 也许,如果这能如您所愿,您可以每次使用服务 o 之类的服务检查连接,然后设置一个标志变量,一个静态全局变量,如果有互联网连接则为 true,如果没有则为 false。要检查是否存在,您只需检查此标志即可。

我没试过,我认为这是一个非常糟糕的方法,但我没有找到任何其他解决方案,所以......也许你可以使用 SNTP 客户端而不是 ping 功能(将超时设置为显然价值很小)。

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;
            }
        }

    }

}