Android实现自动连接目标wifi

公司有个自动连接目标wifi的需求,查阅了很多资料,记录一下自己测试有用的方式。
扫描和获取wifi列表可以查看:
https://blog.csdn.net/CSDNzzh95/article/details/131635916
获得wifiInfo: ScanResult数据

android 10以下的版本

        /**
         * wifi设置
         * @param ssid
         * @param pws
         * @param isHasPws
         */
        private fun getWifiConfig(ssid: String, pws: String?): WifiConfiguration {
            val config = WifiConfiguration()
            config.allowedAuthAlgorithms.clear()
            config.allowedGroupCiphers.clear()
            config.allowedKeyManagement.clear()
            config.allowedPairwiseCiphers.clear()
            config.allowedProtocols.clear()
            config.SSID = "\"" + ssid + "\""
            if (pws.isNullOrEmpty()) {
                FdageLog.i(TAG, "  [getWifiConfig] 网络:$ssid  无密码连接")
                config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
            } else {
                FdageLog.i(TAG, "  [getWifiConfig] 网络:$ssid  密码:$pws 连接")
                config.preSharedKey = "\"" + pws + "\""
                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
            }
            return config
        }

使用getWifiConfig方法设置好WifiConfiguration数据
然后使用WifiConfiguration数据,直接连接

         FdageLog.i(TAG, " [connectWifi] 低版本 开始连接${wifiInfo.SSID}")
         var wifiManager: WifiManager = activity.getSystemService(Context.WIFI_SERVICE) as WifiManager
         val wifiConfig = getWifiConfig(wifiInfo.SSID, password)
         val netId = wifiManager!!.addNetwork(wifiConfig)
         wifiManager!!.enableNetwork(netId, true)

低版本连接还是比较简单直接的,经测试基本能连接成功

android 10以上高版本连接

方式一:使用WifiNetworkSuggestion实现

    @RequiresApi(Build.VERSION_CODES.Q)
    fun connect2(wifiInfo: ScanResult, password: String?) {
        Log.d(TAG, " [connect2] removeNetworkSuggestions")
        val suggestion = if (password.isNullOrEmpty()) {
            WifiNetworkSuggestion.Builder()
                .setSsid(wifiInfo.SSID)
                .setBssid(MacAddress.fromString(wifiInfo.BSSID))
                .build()
        } else if (wifiInfo.capabilities.contains("wpa3", true)) {
            Log.d(TAG, " [connect2] 高版本 创建 wpa3类型 ${wifiInfo.SSID}  网络配置")
            WifiNetworkSuggestion.Builder()
                .setSsid(wifiInfo.SSID)
                .setBssid(MacAddress.fromString(wifiInfo.BSSID))
                .setWpa3Passphrase(password)
                // Optional (Needs location permission)
                .build()
        } else {
            Log.d(TAG, " [connect2] 高版本 创建 其他类型 ${wifiInfo.SSID}  网络配置")
            WifiNetworkSuggestion.Builder()
                .setSsid(wifiInfo.SSID)
                .setBssid(MacAddress.fromString(wifiInfo.BSSID))
                .setWpa2Passphrase(password)
                // Optional (Needs location permission)
                .build()
        }

        val suggestionsList = listOf(suggestion)
        val status = wifiManager.addNetworkSuggestions(suggestionsList)
        if (status == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
            Log.d(TAG, " [connect2] 高版本 addNetworkSuggestions返回成功")
        } else {
            // do error handling here
            Log.d(TAG, " [connect2] 高版本 addNetworkSuggestions返回失败")
        }
    }

注释都解释了各个步骤的操作,这种方式是向系统提供一个可连接网络的建议,系统会自行判断连接哪个网络:官网解释
经测试:除非手机一个能连接的wifi都没有,系统会连接我们提供的这个wifi,这种方式连接成功的所有app能正常访问网络

方式二:使用WifiNetworkSpecifier连接

        @RequiresApi(Build.VERSION_CODES.Q)
        fun higherVersionConnectWifi(wifiInfo: ScanResult, password: String?) {
            val specifier = if (password.isNullOrEmpty()) {
                WifiNetworkSpecifier.Builder()
                    .setSsid(wifiInfo.SSID)
                    .setBssid(MacAddress.fromString(wifiInfo.BSSID))
                    .build()
            } else if (wifiInfo.capabilities.contains("wpa3", true)) {
                WifiNetworkSpecifier.Builder()
                    .setSsid(wifiInfo.SSID)
                    .setBssid(MacAddress.fromString(wifiInfo.BSSID))
                    .setWpa3Passphrase(password)
                    .build()
            } else {
                WifiNetworkSpecifier.Builder()
                    .setSsid(wifiInfo.SSID)
                    .setBssid(MacAddress.fromString(wifiInfo.BSSID))
                    .setWpa2Passphrase(password)
                    .build()
            }
            val request = NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .setNetworkSpecifier(specifier)
                .build()

             var connectivityManager = activity.getSystemService(Context.WIFI_SERVICE) as WifiManager
            val networkCallback = object : ConnectivityManager.NetworkCallback() {
                override fun onAvailable(network: Network) {
                    // do success processing here..
                    FdageLog.i(TAG, "  [higherVersionConnectWifi] 高版本 onAvailable 连接成功")
                    //绑定网络,否则无法访问网络
                    connectivityManager?.bindProcessToNetwork(network)
                }

                override fun onUnavailable() {
                    // do failure processing here..
                    FdageLog.i(TAG, "  [higherVersionConnectWifi] 高版本 onUnavailable 连接失败")
                    isConnecting = false
                }

            }
            connectivityManager?.requestNetwork(request, networkCallback)
        }

这种方式是点对点的强连接,经测试:基本能够实现强制连接目标wifi,缺点是只能是app本身能访问wifi网络,手机其他app是用不了该网络的,而且app在后台结束后连接也会断开
官网也有详细的说明

两种方式都各有优缺点,根据需求使用就好了
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值