Android WIFI (一) 扫描WIFI中,咱们介绍了如何扫描WIFI,本文介绍下如何衔接WIFI。

权限

改变WIFI状况需求增加权限,如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
</manifest>

经过WifiConfiguration进行衔接(已抛弃)

经过WifiManagerWifiConfiguration衔接WIFI。需求留意的是,此方式在Android Q(10)今后现已抛弃,我的测验机(Android S)使用此方式无法衔接WIFI。

未加密的WIFI

经过WifiManagerWifiConfiguration衔接未加密的WIFI,代码如下:

class WIFIExampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager        
        // 以扫描成果的第一项为例,实践应用按需调整
        val wifiIfno = wifiManager.scanResults.first()
        val ssid = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            it.wifiSsid.toString()
        } else {
            it.SSID
        }
        val wifiConfig = WifiConfiguration()
        wifiConfig.SSID = "\"$ssid\""
        wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
        wifiManager.enableNetwork(addNetwork(wifiConfig), true)
    }
}

加密类型为WEP的WIFI

经过WifiManagerWifiConfiguration衔接加密类型为WEP的WIFI,代码如下:

class WIFIExampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val wifiIfno = wifiManager.scanResults.first()
        val ssid = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            it.wifiSsid.toString()
        } else {
            it.SSID
        }
        val wifiConfig = WifiConfiguration()
        wifiConfig.SSID = "\"$ssid\""
        wifiConfig.wepKeys[0] = "\"${WIFI的暗码}\""
        wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
        wifiConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
        wifiConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED)
        wifiManager.enableNetwork(addNetwork(wifiConfig), true)
    }
}

此加密类型现已过期,根本不再使用。

加密类型为WPA的WIFI

经过WifiManagerWifiConfiguration衔接加密类型为WPA的WIFI,代码如下:

class WIFIExampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val wifiIfno = wifiManager.scanResults.first()
        val ssid = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            it.wifiSsid.toString()
        } else {
            it.SSID
        }
        val wifiConfig = WifiConfiguration()
        wifiConfig.SSID = "\"$ssid\""
        wifiConfig.preSharedKey = "\"${WIFI的暗码}\""
        wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
        wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA)
        wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN)
        wifiManager.enableNetwork(addNetwork(wifiConfig), true)
    }
}

经过WifiNetworkSpecifier进行衔接

能够经过ConnectivityManagerWifiNetworkSpecifier衔接WIFI。

官方文档

未加密的WIFI

经过ConnectivityManagerWifiNetworkSpecifier衔接未加密的WIFI,代码如下:

class WIFIExampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val wifiIfno = wifiManager.scanResults.first()
        val ssid = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            it.wifiSsid.toString()
        } else {
            it.SSID
        }
        val specifier = WifiNetworkSpecifier.Builder()
            .setSsid(ssid)
            .setBssid(MacAddress.fromString(wifiIfno.BSSID))
            .build()
        val request = NetworkRequest.Builder()
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            .setNetworkSpecifier(specifier)
            .build()
        connectivityManager.requestNetwork(request, object : ConnectivityManager.NetworkCallback() {
            override fun onAvailable(network: Network) {
                super.onAvailable(network)
                connectivityManager.run {
                    if (boundNetworkForProcess != network) {
                        if (boundNetworkForProcess != network) {
                            bindProcessToNetwork(network)
                        }
                    }
                }
            }
        })
    }
}

加密类型为WPA的WIFI

经过ConnectivityManagerWifiNetworkSpecifier衔接加密类型为WPA的WIFI,代码如下:

class WIFIExampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val wifiIfno = wifiManager.scanResults.first()
        val ssid = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            it.wifiSsid.toString()
        } else {
            it.SSID
        }
        val specifierBuilder = WifiNetworkSpecifier.Builder()
            .setSsid(ssid)
            .setBssid(MacAddress.fromString(wifiIfno.BSSID))
        if (wifiInfo.capabilities.contains("wpa3", true)) {
            specifierBuilder.setWpa3Passphrase(password)
        } else {
            specifierBuilder.setWpa2Passphrase(password)
        }
        val request = NetworkRequest.Builder()
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            .setNetworkSpecifier(specifierBuilder.build())
            .build()
        connectivityManager.requestNetwork(request, object : ConnectivityManager.NetworkCallback() {
            override fun onAvailable(network: Network) {
                super.onAvailable(network)
                connectivityManager.run {
                    if (boundNetworkForProcess != network) {
                        if (boundNetworkForProcess != network) {
                            bindProcessToNetwork(network)
                        }
                    }
                }
            }
        })
    }
}

测验成果

效果如图:

Android WIFI(二)连接WIFI

能够看到,尽管提示衔接成功,可是无法翻开网页,具体原因不知道,接下来会再研讨研讨。

经过WifiNetworkSuggestion进行衔接

能够经过WifiManagerWifiNetworkSuggestion衔接WIFI。

需求留意,假如用户在体系的WIFI列表中断开某个已衔接的主张WIFI,那么该WIFI会被拉入黑名单24小时。在黑名单期间,体系不会自动衔接该WIFI,即使删除偏重新增加主张也是如此。

官方文档

未加密的WIFI

经过WifiManagerWifiNetworkSuggestion衔接未加密的WIFI,代码如下:

class WIFIExampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val wifiIfno = wifiManager.scanResults.first()
        val ssid = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            it.wifiSsid.toString()
        } else {
            it.SSID
        }
        val suggestion = WifiNetworkSuggestion.Builder()
            .setSsid(ssid)
            .setBssid(MacAddress.fromString(wifiIfno.BSSID))
            .build()
        wifiManager?.addNetworkSuggestions(listOf(suggestion))
    }
}

加密类型为WPA的WIFI

经过WifiManagerWifiNetworkSuggestion衔接加密类型为WPA的WIFI,代码如下:

class WIFIExampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val wifiIfno = wifiManager.scanResults.first()
        val ssid = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            it.wifiSsid.toString()
        } else {
            it.SSID
        }
        val suggestionBuilder = WifiNetworkSuggestion.Builder()
            .setSsid(ssid)
            .setBssid(MacAddress.fromString(wifiIfno.BSSID))
        if (wifiInfo.capabilities.contains("wpa3", true)) {
            suggestionBuilder.setWpa3Passphrase(password)
        } else {
            suggestionBuilder.setWpa2Passphrase(password)
        }
        wifiManager.addNetworkSuggestions(listOf(suggestionBuilder.build()))
    }
}

测验成果

效果如图:

能够看到,经过这种方式衔接WIFI,能够正常的翻开网页。

示例

在示例Demo中增加了相关的演示代码。

ExampleDemo github

ExampleDemo gitee