我不希望我的用户尝试下载任何东西,除非他们连接了Wi-Fi。然而,我似乎只能判断是否启用了Wi-Fi,但他们仍然可能有3G连接。

android.net.wifi.WifiManager m = (WifiManager) getSystemService(WIFI_SERVICE);
android.net.wifi.SupplicantState s = m.getConnectionInfo().getSupplicantState();
NetworkInfo.DetailedState state = WifiInfo.getDetailedStateOf(s);
if (state != NetworkInfo.DetailedState.CONNECTED) {
    return false;
}

然而,这种状态并不是我所期望的。即使Wi-Fi是连接的,我得到OBTAINING_IPADDR作为状态。


当前回答

试试这个方法。

public boolean isInternetConnected() {
    ConnectivityManager conMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    boolean ret = true;
    if (conMgr != null) {
        NetworkInfo i = conMgr.getActiveNetworkInfo();

        if (i != null) {
            if (!i.isConnected()) {
                ret = false;
            }

            if (!i.isAvailable()) {
                ret = false;
            }
        }

        if (i == null)
            ret = false;
    } else
        ret = false;
    return ret;
}

这种方法将有助于找到互联网连接是否可用。

其他回答

这对我来说很管用:

    ConnectivityManager conMan = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

    // Mobile
    State mobile = conMan.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();

    // Wi-Fi
    State wifi = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();

    // And then use it like this:

    if (mobile == NetworkInfo.State.CONNECTED || mobile == NetworkInfo.State.CONNECTING)
    {
        Toast.makeText(Wifi_Gprs.this,"Mobile is Enabled :) ....",Toast.LENGTH_LONG).show();
    }
    else if (wifi == NetworkInfo.State.CONNECTED || wifi == NetworkInfo.State.CONNECTING)
    {
        Toast.makeText(Wifi_Gprs.this,"Wifi is Enabled  :) ....",Toast.LENGTH_LONG).show();
    }
    else
    {
        Toast.makeText(Wifi_Gprs.this,"No Wifi or Gprs Enabled :( ....",Toast.LENGTH_LONG).show();
    }

并添加以下权限:

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

我简单地使用以下方法:

SupplicantState supState; 
wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
supState = wifiInfo.getSupplicantState();

它将在调用getSupplicantState()时返回这些状态之一;

ASSOCIATED - Association completed. ASSOCIATING - Trying to associate with an access point. COMPLETED - All authentication completed. DISCONNECTED - This state indicates that client is not associated, but is likely to start looking for an access point. DORMANT - An Android-added state that is reported when a client issues an explicit DISCONNECT command. FOUR_WAY_HANDSHAKE - WPA 4-Way Key Handshake in progress. GROUP_HANDSHAKE - WPA Group Key Handshake in progress. INACTIVE - Inactive state. INVALID - A pseudo-state that should normally never be seen. SCANNING - Scanning for a network. UNINITIALIZED - No connection.

虽然Jason的回答是正确的,但现在getNetWorkInfo (int)是一个不推荐使用的方法。所以,下一个函数将是一个很好的选择:

public static boolean isWifiAvailable (Context context)
{
    boolean br = false;
    ConnectivityManager cm = null;
    NetworkInfo ni = null;

    cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    ni = cm.getActiveNetworkInfo();
    br = ((null != ni) && (ni.isConnected()) && (ni.getType() == ConnectivityManager.TYPE_WIFI));

    return br;
}

The following code (in Kotlin) works from API 21 until at least current API version (API 29). The function getWifiState() returns one of 3 possible values for the WiFi network state: Disable, EnabledNotConnected and Connected that were defined in an enum class. This allows to take more granular decisions like informing the user to enable WiFi or, if already enabled, to connect to one of the available networks. But if all that is needed is a boolean indicating if the WiFi interface is connected to a network, then the other function isWifiConnected() will give you that. It uses the previous one and compares the result to Connected.

它受到了之前一些答案的启发,但试图解决Android API的发展或IP V6的可用性缓慢增加所带来的问题。 诀窍是使用:

wifiManager.connectionInfo.bssid != null 

而不是:

getIpAddress() == 0,仅对IP V4或有效 getNetworkId() == -1现在需要另一个特殊权限(位置)

参考文档:https://developer.android.com/reference/kotlin/android/net/wifi/WifiInfo.html#getbssid 如果没有连接到网络,它将返回null。即使我们没有获得真实值的权限,如果我们连接了,它仍然会返回null以外的值。

同时也要记住以下几点:

在android.os.Build之前发布。VERSION_CODES#N,该对象 应该只能从Context中获得#getApplicationContext(),和 类型中的内存泄漏,而不是来自任何其他派生上下文 调用过程。

在舱单中,不要忘记添加:

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

建议代码为:

class MyViewModel(application: Application) : AndroidViewModel(application) {

   // Get application context
    private val myAppContext: Context = getApplication<Application>().applicationContext

   // Define the different possible states for the WiFi Connection
    internal enum class WifiState {
        Disabled,               // WiFi is not enabled
        EnabledNotConnected,    // WiFi is enabled but we are not connected to any WiFi network
        Connected,              // Connected to a WiFi network
    }

    // Get the current state of the WiFi network
    private fun getWifiState() : WifiState {

        val wifiManager : WifiManager = myAppContext.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager

        return if (wifiManager.isWifiEnabled) {
                    if (wifiManager.connectionInfo.bssid != null)
                        WifiState.Connected
                    else
                        WifiState.EnabledNotConnected
               } else {
                    WifiState.Disabled
               }
    }

    // Returns true if we are connected to a WiFi network
    private fun isWiFiConnected() : Boolean {
        return (getWifiState() == WifiState.Connected)
    }
}

这适用于最新版本的android:

fun getConnectionType(context: Context): ConnectivityType {
    var result = NONE
    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (cm != null) {
            val capabilities = cm.getNetworkCapabilities(cm.activeNetwork)
            if (capabilities != null) {
                when {
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
                        result = WIFI
                    }
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
                        result = MOBILE_DATA
                    }
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> {
                        result = VPN
                    }
                }
            }
        }
    } else {
        if (cm != null) {
            val activeNetwork = cm.activeNetworkInfo
            if (activeNetwork != null) {
                // connected to the internet
                when (activeNetwork.type) {
                    ConnectivityManager.TYPE_WIFI -> {
                        result = WIFI
                    }
                    ConnectivityManager.TYPE_MOBILE -> {
                        result = MOBILE_DATA
                    }
                    ConnectivityManager.TYPE_VPN -> {
                        result = VPN
                    }
                }
            }
        }
    }
    return result
}

enum class ConnectivityType {
    NONE,
    MOBILE_DATA,
    WIFI,
    VPN,
}

在清单中:

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