Android开发,如何知道Wi-Fi已连接了一个热点
我知道的有两种(欢迎知道更多的童鞋补充~):
1:通过ConnectivityManager,代码如下:
public static boolean isWifiConnected() {
// BaseApplication.getApp()是当前Application
ConnectivityManager mConnectivityManager = (ConnectivityManager) BaseApplication.getApp()
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (null == mConnectivityManager) {
return false;
}
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null && mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
return mNetworkInfo.isAvailable();
}
return false;
}
备注:方法1是某个框架中的代码,用的是Java。下面介绍的方式是我根据项目实际情况采用的方式(除了能获取网络类型是Wi-Fi,还能拿到Wi-Fi的额外信息),用的是Kotlin所写。
2:通过WifiManager,这种方式不仅仅能判断网络类型是Wi-Fi,还能拿到当前Wi-Fi的一些额外信息,如ssid,bssid等。
不过目前这种方式因Android Q(Android 10)发生了一些变化。在Android Q以前,这种方式能没有问题 。在Android Q以后,Android Q对设备的系统标识(MAC、IMEI、序列号)增加了更多的限制和修改(看到这里的童鞋可以看看关于Android Q的适配)。Android Q修改了Wi-Fi模块的一些Api。如果用户不授予位置权限(位置权限要动态申请),得到的wifi信息中很多字段如bssid、ssid等将是默认值。
下面介绍不用申请位置权限也能判断网络类型是否是Wi-Fi
1:获取WifiManager
// Kotlin扩展函数
val Context.wifi: WifiManager
get() = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
2:获取当前Wi-Fi连接信息WifiInfo
if (wifi.isWifiEnabled) {
// Wi-Fi模块开启,获取连接信息
val info = wifi.connectionInfo // info是一个WifiInfo对象
if(SupplicantState.COMPLETED == wifi.connectionInfo.supplicantState) {
// 已连接上某个Wi-Fi,可以判定网络类型是Wi-Fi,不授予位置权限也能成功判断
}
} else {
// 肯定不是Wi-Fi...
}
备注:
在Android 10中,bssid,ssid将不可靠,具体可看WifiInfo源码介绍的注释,在没有权限的时候不管是否连接wifi,获取到的bssid是"02:00:00:00:00:00",获取到的ssid是"< unknown ssid >"
/*
WifiInfo中关于bssid(一般情况下,如果手机连上路由器,可以理解为bssid为路由器的wifi芯片的mac,一个路由器除了wifi芯片的mac,还有有线wan口模块的mac,介绍的有点多~~~~~)的介绍。
虽然官方源码介绍,如果手机没有连上wi-fi热点,bssid为null。如果没有授予相关权限,bssid将返回默认值"02:00:00:00:00:00"。这个我在国产机(小米 10)可不是这样,如果没有授予相关权限,不管手机当前wifi模块是否开启,是否连上一个wi-fi,获取到都是这个默认值。
*/
/**
* Return the basic service set identifier (BSSID) of the current access point.
* <p>
* The BSSID may be
* <lt>{@code null}, if there is no network currently connected.</lt>
* <lt>{@code "02:00:00:00:00:00"}, if the caller has insufficient permissions to access the
* BSSID.<lt>
* </p>
*
* @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX}
*/
public String getBSSID() {
return mBSSID;
}
/**
* Returns the service set identifier (SSID) of the current 802.11 network.
* <p>
* If the SSID can be decoded as UTF-8, it will be returned surrounded by double
* quotation marks. Otherwise, it is returned as a string of hex digits.
* The SSID may be
* <lt><unknown ssid>, if there is no network currently connected or if the caller has
* insufficient permissions to access the SSID.<lt>
* </p>
* <p>
* Prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method
* always returned the SSID with no quotes around it.
* </p>
*
* @return the SSID.
*/
public String getSSID() {
if (mWifiSsid != null) {
String unicode = mWifiSsid.toString();
if (!TextUtils.isEmpty(unicode)) {
return "\"" + unicode + "\"";
} else {
String hex = mWifiSsid.getHexString();
return (hex != null) ? hex : WifiSsid.NONE;
}
}
return WifiSsid.NONE;
}