美文网首页
WIFI的相关操作

WIFI的相关操作

作者: 望北8261 | 来源:发表于2019-10-22 18:37 被阅读0次

    首先要获取 WifiManager,后面的所有操作基本上都要用到。

    val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager
    

    打开关闭WIFI

    打开或者关闭WIFI直接调用 WifiManager.isWifiEnabled = true / false 就可以了,但是要监听操作结果的话,有两种方法,一个是监听广播,一个是写循环主动查询,我个人觉得还是主动查询可靠点,下面是我封装的方法:

    /**
     * 异步打开、关闭wifi,并回调。10秒超时。
     * @param enabled 打开/关闭 WIFI。
     * @param callback 结果回调,success:打开/关闭成功。UI线程回调。
     */
    private fun WifiManager.enable(enabled: Boolean, callback: (success: Boolean) -> Unit) {
        GlobalScope.launch(Dispatchers.IO) {
            // 当前状态一致,直接回调
            if (isWifiEnabled == enabled) {
                GlobalScope.launch(Dispatchers.Main) { callback.invoke(true) }
                return@launch
            }
    
            isWifiEnabled = enabled
    
            repeat(10) {
                delay(1000)
                // 当前状态一致,直接回调
                if (isWifiEnabled == enabled) {
                    GlobalScope.launch(Dispatchers.Main) { callback.invoke(true) }
                    return@launch
                }
            }
    
            GlobalScope.launch(Dispatchers.Main) { callback.invoke(false) }
        }
    }
    
    // 这样调用即可
    wifiManager.enable(isChecked) { success ->
        // 直接用 wifiManager.isWifiEnabled 判断更可靠点
        if (wifiManager.isWifiEnabled) {
            // WIFI 已打开
        } else {
            // WIFI 已关闭
        }
    }
    

    扫描WIFI

    扫描结果通过 wifiManager.scanResults 获取,但是获取到的可能是以前的扫描结果,所以我们要等收到广播后再获取结果。

    // 广播接收器
    private val receiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent?.action == WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) {
                wifiManager.scanResults.filter {
                    !TextUtils.isEmpty(it.SSID)
                }.forEach {scanResult->
                    LogUtils.d(TAG, scanResult)
                    // 展示列表
                }
            }
        }
    }
    
    // 注册广播
    registerReceiver(receiver, IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
    // 扫描
    wifiManager.startScan()
    // 注销广播
    unregisterReceiver(receiver)
    

    连接WIFI

    连接WIFI要调用好几个接口,首先要根据帐号密码生成WifiConfiguration,然后addNetwork(config),返回-1表示失败,addNetwork只是把配置添加到配置列表,还需要调用 enableNetwork(networkId, true)才是真正的连接WIFI,最后调用saveConfiguration保存一下。操作结果依然是通过广播接收。

    1、生成WifiConfiguration比较复杂,这里写了个独立的方法,代码是网上的稍作修改了。

    // 获取已经存在的SSID对应的配置
    private fun WifiManager.getConfiguredNetwork(ssid: String): WifiConfiguration? {
        configuredNetworks.forEach {
            if (it.SSID == "\"$ssid\"") return it
        }
        return null
    }
    
    private fun WifiManager.createWifiConfiguration(ssid: String, password: String, scanResult: ScanResult? = null): WifiConfiguration {
        // 判断是否已经存在
        val config = getConfiguredNetwork(ssid)
        if (config != null) {
            LogUtils.d(TAG, "已经存在 $ssid 执行移除操作")
            val successful = removeNetwork(config.networkId)
            LogUtils.d(TAG, "移除操作 ${if (successful) "成功" else "失败"}")
        }
    
        val capabilities = scanResult?.capabilities ?: "wpa"
        return WifiConfiguration().apply {
            allowedAuthAlgorithms.clear()
            allowedGroupCiphers.clear()
            allowedKeyManagement.clear()
            allowedPairwiseCiphers.clear()
            allowedProtocols.clear()
            SSID = "\"" + ssid + "\""
    
            when {
                capabilities.contains("wep", ignoreCase = true) -> {
                    hiddenSSID = true
                    wepKeys[0] = "\"" + password + "\""
                    allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED)
                    allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
                    allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
                    allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40)
                    allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104)
                    allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
                    wepTxKeyIndex = 0
                }
                capabilities.contains("psk", ignoreCase = true) -> {
                    preSharedKey = "\"" + password + "\""
                    hiddenSSID = true
                    allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
                    allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
                    allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
                    allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
                    allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
                    allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
                    status = WifiConfiguration.Status.ENABLED
                }
                else -> {
                    // 没有密码
                    allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
                }
            }
        }
    }
    

    2、连接

    // 这里增加个变量多重判断一下
    private var enableNetworkSuccessful = false
    
    private fun connect() {
        val ssid = et_name.text.toString()
        val password = et_password.text.toString()
    
        val config = wifiManager.createWifiConfiguration(ssid, password, wifiWrapper?.wifi)
        LogUtils.d(TAG, "创建 WifiConfiguration:$config")
        val networkId = wifiManager.addNetwork(config)
        LogUtils.d(TAG, "addNetwork 返回:$networkId")
        enableNetworkSuccessful = wifiManager.enableNetwork(networkId, true)
        LogUtils.d(TAG, "enableNetwork 返回:$enableNetworkSuccessful")
        if (enableNetworkSuccessful) {
            val successful = wifiManager.saveConfiguration()
            LogUtils.d(TAG, "saveConfiguration 返回:$successful")
        }
    }
    

    3、监听结果

    private val receiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            when (intent?.action) {
                WifiManager.SUPPLICANT_STATE_CHANGED_ACTION -> {
                    LogUtils.i(TAG, "收到广播:SUPPLICANT_STATE_CHANGED_ACTION")
                    val error = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 123)
                    if (WifiManager.ERROR_AUTHENTICATING == error) {
                        LogUtils.e(TAG, "密码错误")
                        ToastUtils.show("密码错误")
                        progressDialog.dismiss()
                    }
                }
                WifiManager.NETWORK_STATE_CHANGED_ACTION -> {
                    LogUtils.i(TAG, "收到广播:NETWORK_STATE_CHANGED_ACTION")
                    try {
                        val info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO) as? NetworkInfo
                        LogUtils.i(TAG, "EXTRA_NETWORK_INFO=$info")
                        when (info?.state) {
                            NetworkInfo.State.CONNECTING -> ToastUtils.show("正在连接...")
                            NetworkInfo.State.CONNECTED -> {
                                // 连接成功
                                if (enableNetworkSuccessful) {
                                    LogUtils.i(TAG, "CONNECTED")
                                    ToastUtils.show("连接成功")
                                    successful = true
                                    progressDialog.dismiss()
                                    dismiss()
                                }
                            }
                            else -> Unit
                        }
                    } catch (e: Exception) {
                        LogUtils.printStackTrace(e)
                    }
                }
            }
        }
    }
    
    // 注册广播
    registerReceiver(receiver, IntentFilter().apply {
        addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)
        addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
    })
    // 注销广播
    unregisterReceiver(receiver)
    

    相关文章

      网友评论

          本文标题:WIFI的相关操作

          本文链接:https://www.haomeiwen.com/subject/mzfcvctx.html