我不希望我的用户尝试下载任何东西,除非他们连接了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作为状态。
这对我来说很管用:
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.
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" />