- 测试手机 版本10.0,7.1
- android 6.0后需要申请运行时权限
是否打开wifi
private fun getWifiManager(): WifiManager {
return getAppContext().applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
}
private fun getConnectivityManager(): ConnectivityManager {
return getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
}
// 是否打开wifi
getWifiManager().isWifiEnabled()
打开wifi
- 在android 29之后不允许直接开启wifi
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
ActivityUtils.startActivity(intent)
} else {
NetworkUtils.setWifiEnabled(true)
}
获取wifi列表
- 在android 23之后需要开启位置信息
- 若为空检查wifi和位置信息是否开启
// 开始扫描wifi getWifiManager().startScan() // 获取wifi列表 getWifiManager().getScanResults() // 是否打开定位 val manager = getAppContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager LocationManagerCompat.isLocationEnabled(manager)连接wifi
- android 29之后废弃了原有api并对wifi能力进行了限制,开启网络不可用,待处理(暂时好像只能降低targetSdkVersion版本)
- android 29之后若在局域网内传递数据,注意在wifi监听中调用bindProcessTonetwork(network)
fun connectWiFi(name: String, password: String? = null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val wifiNetworkSpecifier = WifiNetworkSpecifier.Builder().run {
setSsid(name)
setIsHiddenSsid(true)
if (password != null) {
setWpa2Passphrase(password)
}
build()
}
val networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
// 在荣耀20上测试若开启网络能力不可用,待处理
// .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.setNetworkSpecifier(wifiNetworkSpecifier)
.build()
getConnectivityManager().requestNetwork(networkRequest, mNetworkCallbackWifi)
} else {
val config = WifiConfiguration()
config.allowedAuthAlgorithms.clear()
config.allowedGroupCiphers.clear()
config.allowedKeyManagement.clear()
config.allowedPairwiseCiphers.clear()
config.allowedProtocols.clear()
config.SSID = ""$name""
isExistWiFi(name)?.let {
getWifiManager().removeNetwork(it.networkId)
}
if (password == null) {
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
} else {
config.preSharedKey = ""$password""
config.hiddenSSID = true
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
config.status = WifiConfiguration.Status.ENABLED
}
getWifiManager().disableNetwork(getWifiManager().connectionInfo.networkId)
val netId = getWifiManager().addNetwork(config)
getWifiManager().enableNetwork(netId, true)
}
}
private fun isExistWiFi(ssid: String): WifiConfiguration? {
val configs = getWifiManager().configuredNetworks
for (config in configs) {
if (config.SSID == ""$ssid"") {
return config
}
}
return null
}
wifi监听
- 在android 29之前通过广播监听
- 在android 29之后添加监听api,若只监听wifi连接和断开推荐使用新的api
// 广播
fun registerWifiChangeReceiver() {
val filter = IntentFilter().apply {
addAction("android.net.wifi.STATE_CHANGE")
addAction("android.net.wifi.WIFI_STATE_CHANGED")
addAction("android.intent.action.CONFIGURATION_CHANGED")
}
getAppContext().registerReceiver(WifiBroadcastReceiver(), filter)
}
class WifiBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (WifiManager.WIFI_STATE_CHANGED_ACTION == intent?.action)
when (intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0)) {
WifiManager.WIFI_STATE_DISABLED -> Timber.d("wifi关闭")
WifiManager.WIFI_STATE_ENABLED -> Timber.d("wifi打开")
}
if (WifiManager.NETWORK_STATE_CHANGED_ACTION == intent?.action)
when (intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO)?.state) {
NetworkInfo.State.ConNECTED -> Timber.d("wifi连接")
NetworkInfo.State.DISConNECTED -> Timber.d("wifi关闭连接")
else -> Timber.d("unknown")
}
}
}
private var mWifiConnectListener: ((Boolean) -> Unit)? = null
fun registerWifiConnectListener(block: (Boolean) -> Unit) {
this.mWifiConnectListener = block
val manager = getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkRequestWifi = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build()
manager.registerNetworkCallback(networkRequestWifi, mNetworkCallbackWifi)
}
private val mNetworkCallbackWifi = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
getConnectivityManager().bindProcessToNetwork(network)
}
Timber.d("wifi连接")
mWifiConnectListener?.invoke(true)
}
override fun onLost(network: Network) {
super.onLost(network)
Timber.d("wifi断开")
mWifiConnectListener?.invoke(false)
}
}
断开wifi
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
getConnectivityManager().bindProcessToNetwork(null)
} else {
getWifiManager().disconnect()
}
其他方法
fun calculateSignalLevel(rssi: Int, numLevels: Int): Int {
return when {
rssi <= MIN_RSSI -> {
0
}
rssi >= MAX_RSSI -> {
numLevels - 1
}
else -> {
val inputRange: Float = (MAX_RSSI - MIN_RSSI).toFloat()
val outputRange = (numLevels - 1).toFloat()
((rssi - MIN_RSSI).toFloat() * outputRange / inputRange).toInt()
}
}
}
fun getConnectWifiName(): String? {
val wifiInfo: WifiInfo = getWifiManager().connectionInfo
var ssid = wifiInfo.ssid
if (ssid.contains(""")) {
ssid = ssid.replace(""", "").trim { it <= ' ' }
}
return ssid
}
fun isWifiConnected(): Boolean {
val ni = getConnectivityManager().activeNetworkInfo
return ni != null && ni.type == ConnectivityManager.TYPE_WIFI
}
总结
android 10.0 版本对wifi使用增加了更多的限制,兼容的难度不如降低版本,若有更好地解决方案请在评论区告诉我一下。



