ConnectivityManager getNetworkInfo(int)已被弃用。

182

使用compileSdkVersion 23,但尝试支持至少到9。

getNetworkInfo(int)在23中已被弃用。建议使用getAllNetworks()getNetworkInfo(Network)代替。但是这两个都需要最低API 21。

有没有一个可以在支持包中使用的类来帮助解决这个问题?

我知道有一个解决方案before,但是我的最低API要求为9,这是一个问题。


您可以在运行时检查构建版本,并使用适当的方法。 - stinepike
1
这个会不会仍然抛出一个弃用警告? - kyleED
请查看我的ConnectivityObserver类,它封装了Android Nougat以下和以上的API方法。 - JJD
getNetworkInfo(Network)在API级别29中已被弃用。 - cesargastonec
https://dev59.com/JVQJ5IYBdhLWcg3wlm_B#65251284 - Quick learner
28个回答

182

您可以使用:

getActiveNetworkInfo();

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null) { 
    // connected to the internet
    if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
        // connected to wifi
    } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
        // connected to mobile data
    }
} else {
    // not connected to the internet
}

或者使用 switch case

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null) { 
    // connected to the internet
    switch (activeNetwork.getType()) {
        case ConnectivityManager.TYPE_WIFI:
            // connected to wifi
            break;
        case ConnectivityManager.TYPE_MOBILE:
            // connected to mobile data
            break;
        default:
            break;
    }
} else {
    // not connected to the internet
}

18
从Android 9,SDK 28开始,这已被弃用。 - Zbarcea Christian
3
@CheeseBread,这是我发布的相同代码。整个问题的重点在于getNetworkInfo已被弃用 :) - m0skit0
38
activeNetwork.getType()已被弃用,而ConnectivityManager.TYPE_WIFI也已被弃用。`(意思是需要更新代码以使用新的替代方法) - noobEinstien
12
现在的意思是:替换为cm.getNetworkCapabilities(cm.activeNetwork).hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) - tmm1
22
我已经厌倦了这种不断贬值的循环。 - Oluwasegun Wahaab
显示剩余7条评论

114

2020年2月更新:

接受的答案在28 (Android P)中再次过时,但其替代方法仅适用于23 (Android M)。为了支持旧设备,在Kotlin和Java中编写了一个帮助函数。

如何使用:

int type = getConnectionType(getApplicationContext());

它返回一个int,你可以在代码中将其更改为enum

0:没有可用的互联网(可能处于飞行模式或正在加入Wi-Fi)。

1:蜂窝移动数据(3G / 4G / LTE等)。

2:Wi-Fi。

3:VPN

您可以复制Kotlin或Java版本的辅助函数。

Kotlin:

@IntRange(from = 0, to = 3)
fun getConnectionType(context: Context): Int {
    var result = 0 // Returns connection type. 0: none; 1: mobile data; 2: wifi; 3: vpn
    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        cm?.run {
            cm.getNetworkCapabilities(cm.activeNetwork)?.run {
                if (hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    result = 2
                } else if (hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = 1
                } else if (hasTransport(NetworkCapabilities.TRANSPORT_VPN)){
                    result = 3
                }
            }
        }
    } else {
        cm?.run {
            cm.activeNetworkInfo?.run {
                if (type == ConnectivityManager.TYPE_WIFI) {
                    result = 2
                } else if (type == ConnectivityManager.TYPE_MOBILE) {
                    result = 1
                } else if(type == ConnectivityManager.TYPE_VPN) {
                    result = 3
                }
            }
        }
    }
    return result
}

Java:

@IntRange(from = 0, to = 3)
public static int getConnectionType(Context context) {
    int result = 0; // Returns connection type. 0: none; 1: mobile data; 2: wifi; 3: vpn
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (cm != null) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            if (capabilities != null) {
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    result = 2;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = 1;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
                    result = 3;
                }
            }
        }
    } else {
        if (cm != null) {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork != null) {
                // connected to the internet
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                    result = 2;
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                    result = 1;
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_VPN) {
                    result = 3;
                }
            }
        }
    }
    return result;
}

2
由于有两个可能的结果,最好使用布尔值而不是返回整数... - Christian
4
如黄色部分所解释的那样,这个帮助函数会返回 3 种可能的状态:无网络蜂窝数据Wi-Fi。如果你不关心连接类型,可以自由修改代码以适应你的应用程序。 - WSBT
1
@Lukas,如果你使用包装类Boolean而不是原始类型boolean,就必须小心。在if语句中,你将不得不添加对null的检查。此外,如果明天引入了另一种新的网络能力传输模式...那么使用整数进行分支处理会有所帮助,你也可以选择使用switch case。 - Shadow Droid
24
我厌倦了这种不断的贬值循环。 - Oluwasegun Wahaab
1
TRANSPORT_ETHERNET是什么情况? - Bouh
显示剩余6条评论

73

截至2018年10月,接受的答案已被弃用。

getType()和类型本身现已在API Level 28中弃用。根据Javadoc:

调用者应该转而使用NetworkCapabilities#TRANSPORT*常量之一检查NetworkCapabilities#hasTransport

为了使用NetworkCapabilities,您需要将Network实例传递给getNetworkCapabilities()方法。要获取该实例,您需要调用在API Level 23中添加的getActiveNetwork()

所以我认为目前安全检查是否连接到Wi-Fi或蜂窝网络的正确方法是:

public static boolean isNetworkConnected() {
    final ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (cm != null) {
        if (Build.VERSION.SDK_INT < 23) {
            final NetworkInfo ni = cm.getActiveNetworkInfo();

            if (ni != null) {
                return (ni.isConnected() && (ni.getType() == ConnectivityManager.TYPE_WIFI || ni.getType() == ConnectivityManager.TYPE_MOBILE));
            }
        } else {
            final Network n = cm.getActiveNetwork();

            if (n != null) {
                final NetworkCapabilities nc = cm.getNetworkCapabilities(n);

                return (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
            }
        } 
    }

    return false; 
}

您还可以检查其他类型的TRANSPORT,您可以在此处找到:here.

重要提示:如果您同时连接了Wi-Fi VPN,则您当前的状态可能是TRANSPORT_VPN,因此您可能也需要进行检查。

不要忘记将以下权限添加到AndroidManifest文件中:

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

hasTransport(NetworkCapabilities.TRANSPORT_WIFI) 是否等同于 ni.isConnected() && (ni.getType() == ConnnectivityManager.TYPE_WIFI) ? 我是指 hasTransport() 函数是否也会检查设备是否已连接或正在尝试连接? - Biscuit
再次强调,“NetworkInfo”已经被淘汰,不能再使用“NetWorkInfo”,那么现在有什么替代方案呢? - Prescott Chartier
@PrescottChartier 这段代码片段只在SDK <23的设备上访问NetworkInfo。 - Tom

18

更新的答案(2018年7月19日):

这种方法将帮助您检查互联网连接是否可用。

public static boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (connectivityManager != null) {
        NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
        return (activeNetwork != null && activeNetwork.isConnectedOrConnecting());
    } else {
        return false;
    }
}

旧回答:

为了最佳的代码复用实践,我们对奶酪面包的回答进行改进。

New answer:

为了更好的代码重用实践,我们对“Cheese Bread”的答案进行了修改。

public static boolean isNetworkAvailable(Context context) {
    int[] networkTypes = {ConnectivityManager.TYPE_MOBILE,
            ConnectivityManager.TYPE_WIFI};
    try {
        ConnectivityManager connectivityManager =
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        for (int networkType : networkTypes) {
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            if (activeNetworkInfo != null &&
                    activeNetworkInfo.getType() == networkType)
                return true;
        }
    } catch (Exception e) {
        return false;
    }
    return false;
}

这段代码可以放在Util类中,用于检查手机是否通过Wifi或移动网络连接到互联网,从应用程序的任何部分使用。


3
建议将获取活动网络的操作移至for循环之外。 - shtolik
22
activeNetwork.isConnectedOrConnecting()现已弃用。 - MHSaffari
1
我将activeNetwork.isConnectedOrConnecting()更改为activeNetwork.isConnected。 - Murillo Comino
2
NetworkInfo现在已经过时了。需要再次更新! - SMBiggs

17

2019年2月答案

检查您是否在线:

截至2020年3月,有一份更新的回答支持API.15到API.29,您可以在原始回答后找到它。

boolean isOnline() {
    // Checking internet connectivity
    ConnectivityManager connectivityMgr = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = null;
    if (connectivityMgr != null) {
        activeNetwork = connectivityMgr.getActiveNetworkInfo();
    }
    return activeNetwork != null;
}

Kotlin:

fun isOnline(): Boolean {
    val connectivityMgr = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
        return connectivityMgr.activeNetworkInfo != null

    } else {

        for (network in connectivityMgr.allNetworks) { // added in API 21 (Lollipop)
            val networkCapabilities: NetworkCapabilities? =
                connectivityMgr.getNetworkCapabilities(network)
            return (networkCapabilities!!.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                    networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) &&
                    (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)))
        }
    }
    return false
}

在 Android M 之前/之后获取互联网连接类型

void internetType() {
    // Checking internet connectivity
    ConnectivityManager connectivityMgr = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = null;
    if (connectivityMgr != null) {
        activeNetwork = connectivityMgr.getActiveNetworkInfo();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            NetworkCapabilities nc = connectivityMgr.getNetworkCapabilities(connectivityMgr.getActiveNetwork());
            if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                // connected to mobile data
            } else if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                // connected to wifi
            }
        } else {
            if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                // connected to wifi
            } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                // connected to mobile data
            }
        }
    }
}

所有情况都需要获取访问网络状态的权限。

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

2020年12月更新:

由于 NetworkInfo 已经被弃用,从API 29开始我们必须使用 ConnectivityManager.NetworkCallback 以及它的网络状态变化回调函数 onAvailable()onLost()

使用方法:

  • 你可以使用这个库:InternetConnectivityLibrary 或者直接使用下面介绍的 utility class,它是这个库的一部分。

特点:

  • 它实现了 LifecycleObserver 来保证生命周期友好,避免内存泄漏,在 onDestroy() 方法中进行一些清理。
  • 支持 API 15(冰激凌三明治)到 API 29(Android Q)。
  • 对于 API 21 以下的版本,它使用基于上下文的 BoradcastReceiverNetworkInfo,并对于 API 21 以上的版本,则使用 ConnectivityManager.NetworkCallback
  • 当 WiFi 和蜂窝网络同时开启时,连接监听器不会在从 WiFi 转换到蜂窝网络时中断。
  • 当蜂窝网络开启时,连接监听器不会在 WiFi 连接并成为活动网络时中断(因为这是首选网络)。
  • 如果你使用这个库,就不需要包含这个权限 android.permission.ACCESS_NETWORK_STATE;但如果你使用这个 utility class ,则必须包含该权限。

功能:

  • 获取当前的连接状态(在线/离线)。
  • 持续检查/监听互联网连接并在设备离线或联机时触发回调函数。
  • 获取当前活动互联网连接的类型(WiFi 或移动网络)。
  • 获取所有可用网络的类型(WiFi 或移动网络)。>> 仅支持 API 21+
  • 获取所有可用网络的数量 >> 仅支持 API 21+
@RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
public class ConnectionUtil implements LifecycleObserver {

    private static final String TAG = "LOG_TAG";
    private ConnectivityManager mConnectivityMgr;
    private Context mContext;
    private NetworkStateReceiver mNetworkStateReceiver;
    
    /*
     * boolean indicates if my device is connected to the internet or not
     * */
    private boolean mIsConnected = false;
    private ConnectionMonitor mConnectionMonitor;


    /**
     * Indicates there is no available network.
     */
    private static final int NO_NETWORK_AVAILABLE = -1;


    /**
     * Indicates this network uses a Cellular transport.
     */
    public static final int TRANSPORT_CELLULAR = 0;


    /**
     * Indicates this network uses a Wi-Fi transport.
     */
    public static final int TRANSPORT_WIFI = 1;


    public interface ConnectionStateListener {
        void onAvailable(boolean isAvailable);
    }


    public ConnectionUtil(Context context) {
        mContext = context;
        mConnectivityMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        ((AppCompatActivity) mContext).getLifecycle().addObserver(this);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mConnectionMonitor = new ConnectionMonitor();
            NetworkRequest networkRequest = new NetworkRequest.Builder()
                    .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                    .build();
            mConnectivityMgr.registerNetworkCallback(networkRequest, mConnectionMonitor);
        }

    }


    /**
     * Returns true if connected to the internet, and false otherwise
     *
     * <p>
     * NetworkInfo is deprecated in API 29
     * https://developer.android.com/reference/android/net/NetworkInfo
     * <p>
     * getActiveNetworkInfo() is deprecated in API 29
     * https://developer.android.com/reference/android/net/ConnectivityManager#getActiveNetworkInfo()
     * <p>
     * getNetworkInfo(int) is deprecated as of API 23
     * https://developer.android.com/reference/android/net/ConnectivityManager#getNetworkInfo(int)
     */
    public boolean isOnline() {

        mIsConnected = false;

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            // Checking internet connectivity
            NetworkInfo activeNetwork = null;
            if (mConnectivityMgr != null) {
                activeNetwork = mConnectivityMgr.getActiveNetworkInfo(); // Deprecated in API 29
            }
            mIsConnected = activeNetwork != null;

        } else {
            Network[] allNetworks = mConnectivityMgr.getAllNetworks(); // added in API 21 (Lollipop)

            for (Network network : allNetworks) {
                NetworkCapabilities networkCapabilities = mConnectivityMgr.getNetworkCapabilities(network);
                if (networkCapabilities != null) {
                    if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                            networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED))
                        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                                || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                                || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET))
                            mIsConnected = true;
                }
            }

        }

        return mIsConnected;

    }


    /**
     * Returns
     * <p> <p>
     * <p><p> NO_NETWORK_AVAILABLE >>> when you're offline
     * <p><p> TRANSPORT_CELLULAR >> When Cellular is the active network
     * <p><p> TRANSPORT_WIFI >> When Wi-Fi is the Active network
     * <p>
     */
    public int getActiveNetwork() {

        NetworkInfo activeNetwork = mConnectivityMgr.getActiveNetworkInfo(); // Deprecated in API 29
        if (activeNetwork != null)

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                NetworkCapabilities capabilities = mConnectivityMgr.getNetworkCapabilities(mConnectivityMgr.getActiveNetwork());
                if (capabilities != null)
                    if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                        // connected to mobile data
                        return TRANSPORT_CELLULAR;

                    } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                        // connected to wifi
                        return TRANSPORT_WIFI;
                    }

            } else {
                if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) { // Deprecated in API 28
                    // connected to mobile data
                    return TRANSPORT_CELLULAR;

                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) { // Deprecated in API 28
                    // connected to wifi
                    return TRANSPORT_WIFI;
                }
            }
        return NO_NETWORK_AVAILABLE;
    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public int getAvailableNetworksCount() {

        int count = 0;

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            Network[] allNetworks = mConnectivityMgr.getAllNetworks(); // added in API 21 (Lollipop)
            for (Network network : allNetworks) {
                NetworkCapabilities networkCapabilities = mConnectivityMgr.getNetworkCapabilities(network);
                if (networkCapabilities != null)
                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
                        count++;
            }

        }

        return count;
    }
    

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public List<Integer> getAvailableNetworks() {

        List<Integer> activeNetworks = new ArrayList<>();

        Network[] allNetworks; // added in API 21 (Lollipop)
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            allNetworks = mConnectivityMgr.getAllNetworks();
            for (Network network : allNetworks) {
                NetworkCapabilities networkCapabilities = mConnectivityMgr.getNetworkCapabilities(network);
                if (networkCapabilities != null) {
                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
                        activeNetworks.add(TRANSPORT_WIFI);

                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
                        activeNetworks.add(TRANSPORT_CELLULAR);

                }
            }
        }

        return activeNetworks;
    }


    public void onInternetStateListener(ConnectionStateListener listener) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            mNetworkStateReceiver = new NetworkStateReceiver(listener);
            IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
            mContext.registerReceiver(mNetworkStateReceiver, intentFilter);

        } else {
            mConnectionMonitor.setOnConnectionStateListener(listener);
        }
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        ((AppCompatActivity) mContext).getLifecycle().removeObserver(this);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (mConnectionMonitor != null)
                mConnectivityMgr.unregisterNetworkCallback(mConnectionMonitor);
        } else {
            if (mNetworkStateReceiver != null)
                mContext.unregisterReceiver(mNetworkStateReceiver);
        }

    }


    public class NetworkStateReceiver extends BroadcastReceiver {

        ConnectionStateListener mListener;

        public NetworkStateReceiver(ConnectionStateListener listener) {
            mListener = listener;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getExtras() != null) {

                NetworkInfo activeNetworkInfo = mConnectivityMgr.getActiveNetworkInfo(); // deprecated in API 29

                /*
                 * activeNetworkInfo.getState() deprecated in API 28
                 * NetworkInfo.State.CONNECTED deprecated in API 29
                 * */
                if (!mIsConnected && activeNetworkInfo != null && activeNetworkInfo.getState() == NetworkInfo.State.CONNECTED) {
                    Log.d(TAG, "onReceive: " + "Connected To: " + activeNetworkInfo.getTypeName());
                    mIsConnected = true;
                    mListener.onAvailable(true);

                } else if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
                    if (!isOnline()) {
                        mListener.onAvailable(false);
                        mIsConnected = false;
                    }

                }

            }
        }
    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public class ConnectionMonitor extends ConnectivityManager.NetworkCallback {

        private ConnectionStateListener mConnectionStateListener;

        void setOnConnectionStateListener(ConnectionStateListener connectionStateListener) {
            mConnectionStateListener = connectionStateListener;
        }

        @Override
        public void onAvailable(@NonNull Network network) {

            if (mIsConnected)
                return;

            Log.d(TAG, "onAvailable: ");

            if (mConnectionStateListener != null) {
                mConnectionStateListener.onAvailable(true);
                mIsConnected = true;
            }

        }

        @Override
        public void onLost(@NonNull Network network) {

            if (getAvailableNetworksCount() == 0) {
                if (mConnectionStateListener != null)
                    mConnectionStateListener.onAvailable(false);
                mIsConnected = false;
            }

        }

    }

}

Kotlin版本


class ConnectionUtil(var mContext: Context) : LifecycleObserver {

    private val TAG = "LOG_TAG"

    companion object NetworkType {

        /**
         * Indicates this network uses a Cellular transport.
         */
        const val TRANSPORT_CELLULAR = 0

        /**
         * Indicates this network uses a Wi-Fi transport.
         */
       const val TRANSPORT_WIFI = 1

    }

    private var mConnectivityMgr: ConnectivityManager? = null

    //    private var mContext: Context? = null
    private var mNetworkStateReceiver: NetworkStateReceiver? = null

    /*
     * boolean indicates if my device is connected to the internet or not
     * */
    private var mIsConnected = false
    private var mConnectionMonitor: ConnectionMonitor? = null


    /**
     * Indicates there is no available network.
     */
    private val NO_NETWORK_AVAILABLE = -1


    interface ConnectionStateListener {
        fun onAvailable(isAvailable: Boolean)
    }

    init {
        mConnectivityMgr =
            mContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        (mContext as AppCompatActivity?)!!.lifecycle.addObserver(this)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mConnectionMonitor = ConnectionMonitor()
            val networkRequest = NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .build()
            mConnectivityMgr!!.registerNetworkCallback(networkRequest, mConnectionMonitor!!)
        }
    }


    /**
     * Returns true if connected to the internet, and false otherwise
     *
     * NetworkInfo is deprecated in API 29
     * https://developer.android.com/reference/android/net/NetworkInfo
     *
     * getActiveNetworkInfo() is deprecated in API 29
     * https://developer.android.com/reference/android/net/ConnectivityManager#getActiveNetworkInfo()
     *
     * getNetworkInfo(int) is deprecated as of API 23
     * https://developer.android.com/reference/android/net/ConnectivityManager#getNetworkInfo(int)
     */
    fun isOnline(): Boolean {
        mIsConnected = false
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            // Checking internet connectivity
            var activeNetwork: NetworkInfo? = null
            if (mConnectivityMgr != null) {
                activeNetwork = mConnectivityMgr!!.activeNetworkInfo // Deprecated in API 29
            }
            mIsConnected = activeNetwork != null
        } else {
            val allNetworks = mConnectivityMgr!!.allNetworks // added in API 21 (Lollipop)
            for (network in allNetworks) {
                val networkCapabilities = mConnectivityMgr!!.getNetworkCapabilities(network)
                if (networkCapabilities != null) {
                    if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                        networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
                    ) 
                        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
                        ) mIsConnected = true
                }
            }
        }
        return mIsConnected
    }


    /**
     * Returns:
     *
     * NO_NETWORK_AVAILABLE >>> when you're offline
     * TRANSPORT_CELLULAR >> When Cellular is the active network
     * TRANSPORT_WIFI >> When Wi-Fi is the Active network
     */
    fun getActiveNetwork(): Int {
        val activeNetwork = mConnectivityMgr!!.activeNetworkInfo // Deprecated in API 29
        if (activeNetwork != null) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val capabilities = mConnectivityMgr!!.getNetworkCapabilities(
                mConnectivityMgr!!.activeNetwork
            )
            if (capabilities != null) if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                // connected to mobile data
                return TRANSPORT_CELLULAR
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                // connected to wifi
                return TRANSPORT_WIFI
            }
        } else {
            if (activeNetwork.type == ConnectivityManager.TYPE_MOBILE) { // Deprecated in API 28
                // connected to mobile data
                return TRANSPORT_CELLULAR
            } else if (activeNetwork.type == ConnectivityManager.TYPE_WIFI) { // Deprecated in API 28
                // connected to wifi
                return TRANSPORT_WIFI
            }
        }
        return NO_NETWORK_AVAILABLE
    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    fun getAvailableNetworksCount(): Int {
        var count = 0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            val allNetworks = mConnectivityMgr!!.allNetworks // added in API 21 (Lollipop)
            for (network in allNetworks) {
                val networkCapabilities = mConnectivityMgr!!.getNetworkCapabilities(network)
                if (networkCapabilities != null) if (networkCapabilities.hasTransport(
                        NetworkCapabilities.TRANSPORT_WIFI
                    )
                    || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                ) count++
            }
        }
        return count
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    fun getAvailableNetworks(): List<Int> {
        val activeNetworks: MutableList<Int> = ArrayList()
        val allNetworks: Array<Network> // added in API 21 (Lollipop)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            allNetworks = mConnectivityMgr!!.allNetworks
            for (network in allNetworks) {
                val networkCapabilities = mConnectivityMgr!!.getNetworkCapabilities(network)
                if (networkCapabilities != null) {
                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) activeNetworks.add(
                        TRANSPORT_WIFI
                    )
                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) activeNetworks.add(
                        TRANSPORT_CELLULAR
                    )
                }
            }
        }
        return activeNetworks
    }


    fun onInternetStateListener(listener: ConnectionStateListener) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            mNetworkStateReceiver = NetworkStateReceiver(listener)
            val intentFilter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
            mContext.registerReceiver(mNetworkStateReceiver, intentFilter)
        } else {
            mConnectionMonitor!!.setOnConnectionStateListener(listener)
        }
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy() {
        Log.d(TAG, "onDestroy")
        (mContext as AppCompatActivity?)!!.lifecycle.removeObserver(this)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (mConnectionMonitor != null) mConnectivityMgr!!.unregisterNetworkCallback(
                mConnectionMonitor!!
            )
        } else {
            if (mNetworkStateReceiver != null) mContext.unregisterReceiver(mNetworkStateReceiver)
        }
    }


    inner class NetworkStateReceiver(var mListener: ConnectionStateListener) :
        BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.extras != null) {
                val activeNetworkInfo: NetworkInfo? =
                    mConnectivityMgr?.getActiveNetworkInfo() // deprecated in API 29

                /*
                 * activeNetworkInfo.getState() deprecated in API 28
                 * NetworkInfo.State.CONNECTED deprecated in API 29
                 * */if (!mIsConnected && activeNetworkInfo != null && activeNetworkInfo.state == NetworkInfo.State.CONNECTED) {
                    mIsConnected = true
                    mListener.onAvailable(true)
                } else if (intent.getBooleanExtra(
                        ConnectivityManager.EXTRA_NO_CONNECTIVITY,
                        java.lang.Boolean.FALSE
                    )
                ) {
                    if (!isOnline()) {
                        mListener.onAvailable(false)
                        mIsConnected = false
                    }
                }
            }
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    inner class ConnectionMonitor : NetworkCallback() {
        private var mConnectionStateListener: ConnectionStateListener? = null
        fun setOnConnectionStateListener(connectionStateListener: ConnectionStateListener?) {
            mConnectionStateListener = connectionStateListener
        }

        override fun onAvailable(network: Network) {
            if (mIsConnected) return
            Log.d(TAG, "onAvailable: ")
            if (mConnectionStateListener != null) {
                mConnectionStateListener!!.onAvailable(true)
                mIsConnected = true
            }
        }

        override fun onLost(network: Network) {
            if (getAvailableNetworksCount() == 0) {
                mConnectionStateListener?.onAvailable(false)
                mIsConnected = false
            }
        }
    }

}

@Gokhan Arik.. 很好的发现,我正在解决它。 - Zain
1
请查看此讨论 https://gist.github.com/PasanBhanu/730a32a9eeb180ec2950c172d54bb06a。 - Gokhan Arik
@GokhanArik 感谢您的帮助。我刚刚更新了我的答案并扩展了API的使用,请让我知道是否有任何错误。 - Zain
@GokhanArik 再次感谢,onLost() 现在没问题了,不再需要处理程序/异步代码;通过使用 getAvailableNetworksCount() 跟踪连接网络的数量解决了这个问题。 - Zain
1
@hippietrail 现在已经过去3年了,让我来看看吧。谢谢你的通知。 - undefined
显示剩余4条评论

13

在版本28中,被接受的答案已经过时了,所以这里是我在我的项目中使用的解决方案。

返回连接类型。false:没有互联网连接;true:移动数据|| wifi

public static boolean isNetworkConnected(Context context) { 
    boolean result = false; 
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (cm != null) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            if (capabilities != null) {
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    result = true;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = true;
                }
            }
        }
    } else {
        if (cm != null) {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork != null) {
                // connected to the internet
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                    result = true;
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                    result = true;
                }
            }
        }
    }
    return result;
}

3
activeNetwork.getType()已经过时,可以使用activeNetwork.isConnected()代替。 - Aman Verma

7

这可以帮助某人 Kotlin

fun isNetworkConnected(context: Context) : Boolean {
        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val capabilities =  connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
        capabilities.also {
            if (it != null){
                if (it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
                    return true
                else if (it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)){
                    return true
                }
            }
        }
        return false
    }

1
请完善这段代码并返回internet应该获取wifi或数据包的true值。谢谢! - Najib.Nj
2
从API 23+可用 - martinseal1987

7

许多答案仍然使用已被弃用的 getNetworkType 方法来检查 Android 23 及以下版本的设备网络类型;请使用下面的代码来检查设备是否有互联网连接。

public static boolean isNetworkConnected(Context context) {

    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (cm != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            return capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR));
        } else {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            return activeNetwork != null && activeNetwork.isConnected();
        }
    }

    return false;
}

不要忘记在Manifest文件中添加以下这行代码。

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

5

检查您的网络是否连接到互联网是很好的:

@Suppress("DEPRECATION")
fun isNetworkAvailable(context: Context): Boolean {
    try {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        return if (Build.VERSION.SDK_INT > 22) {
            val an = cm.activeNetwork ?: return false
            val capabilities = cm.getNetworkCapabilities(an) ?: return false
            capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        } else {
            val a = cm.activeNetworkInfo ?: return false
            a.isConnected && (a.type == ConnectivityManager.TYPE_WIFI || a.type == ConnectivityManager.TYPE_MOBILE)
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return false
}

你可能还想检查 NetworkCapabilities.NET_CAPABILITY_VALIDATED - JJD

3

Kotlin版本:

fun isInternetOn(context: Context): Boolean {
   val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
   val activeNetwork = cm?.activeNetworkInfo
   return activeNetwork != null && activeNetwork.isConnected
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接