Android-WiFi密码连接

该文章已生成可运行项目,

Android 开发一款Wifi管理器的问题

  • 问题:我遇到了一个密码连接的操作,正确的密码无法连接,下面是我的核心代码

\app\src\main\java\com\example\qs_wifi\WifiConnectionManager.kt

WifiConnectionManager.kt

package com.example.qs_wifi

import android.content.Context
import android.net.wifi.WifiManager
import android.net.wifi.WifiNetworkSuggestion
import android.os.Build
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import android.net.wifi.WifiConfiguration
import android.net.wifi.WifiInfo
import android.content.IntentFilter
import android.net.wifi.WifiManager.NETWORK_STATE_CHANGED_ACTION
import android.net.wifi.WifiManager.SUPPLICANT_STATE_CHANGED_ACTION
import android.net.wifi.SupplicantState
import android.os.Handler
import android.os.Looper
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import android.content.BroadcastReceiver
import android.content.Intent
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.os.Parcelable

class WifiConnectionManager(private val context: Context) {
    private val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
    private val handler = Handler(Looper.getMainLooper())
    private val TAG = "WifiConnectionManager"

    suspend fun connectToWifi(ssid: String, password: String): Boolean = withContext(Dispatchers.IO) {
        try {
            Log.d(TAG, "=== 开始WiFi连接流程 ===")
            Log.d(TAG, "目标网络: $ssid")
            Log.d(TAG, "密码长度: ${password.length}")
            
            // 检查WiFi是否已启用
            if (!wifiManager.isWifiEnabled) {
                Log.e(TAG, "WiFi未启用,无法连接")
                return@withContext false
            }
            Log.d(TAG, "WiFi已启用")

            // 检查是否已连接
            val currentWifi = wifiManager.connectionInfo
            val currentSsid = currentWifi?.ssid?.removeSurrounding("\"")
            Log.d(TAG, "当前连接的网络: $currentSsid")
            
            if (currentSsid == ssid) {
                Log.d(TAG, "已经连接到目标网络")
                return@withContext true
            }

            // 尝试连接
            Log.d(TAG, "开始尝试连接...")
            val success = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                connectWithSuggestion(ssid, password)
            } else {
                connectWithConfiguration(ssid, password)
            }

            if (!success) {
                Log.e(TAG, "连接请求失败")
                return@withContext false
            }

            // 等待连接结果
            Log.d(TAG, "等待连接结果...")
            waitForConnection(ssid)
        } catch (e: Exception) {
            Log.e(TAG, "连接WiFi时发生错误", e)
            false
        }
    }

    private suspend fun waitForConnection(ssid: String): Boolean = suspendCoroutine { continuation ->
        var isConnected = false
        var retryCount = 0
        val maxRetries = 20 // 最多等待10秒

        val receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                when (intent.action) {
                    NETWORK_STATE_CHANGED_ACTION -> {
                        @Suppress("DEPRECATION")
                        val networkInfo = intent.getParcelableExtra<NetworkInfo>(WifiManager.EXTRA_NETWORK_INFO)
                        Log.d(TAG, "网络状态变化: ${networkInfo?.isConnected}")
                        
                        if (networkInfo?.isConnected == true) {
                            val currentWifi = wifiManager.connectionInfo
                            val currentSsid = currentWifi?.ssid?.removeSurrounding("\"")
                            Log.d(TAG, "当前连接的网络: $currentSsid")
                            
                            if (currentSsid == ssid) {
                                // 验证连接状态
                                val supplicantState = wifiManager.connectionInfo.supplicantState
                                Log.d(TAG, "Supplicant状态: $supplicantState")
                                
                                if (supplicantState == SupplicantState.COMPLETED) {
                                    Log.d(TAG, "连接成功完成")
                                    isConnected = true
                                    context.unregisterReceiver(this)
                                    continuation.resume(true)
                                } else {
                                    Log.d(TAG, "连接未完成,当前状态: $supplicantState")
                                }
                            }
                        }
                    }
                    SUPPLICANT_STATE_CHANGED_ACTION -> {
                        @Suppress("DEPRECATION")
                        val state = intent.getParcelableExtra<SupplicantState>(WifiManager.EXTRA_NEW_STATE)
                        Log.d(TAG, "Supplicant状态变化: $state")
                        
                        when (state) {
                            SupplicantState.DISCONNECTED -> {
                                retryCount++
                                Log.d(TAG, "连接断开,重试次数: $retryCount")
                                if (retryCount >= maxRetries) {
                                    Log.e(TAG, "达到最大重试次数,连接失败")
                                    context.unregisterReceiver(this)
                                    continuation.resume(false)
                                }
                            }
                            SupplicantState.AUTHENTICATING -> {
                                Log.d(TAG, "正在验证...")
                            }
                            SupplicantState.ASSOCIATING -> {
                                Log.d(TAG, "正在关联...")
                            }
                            SupplicantState.ASSOCIATED -> {
                                Log.d(TAG, "已关联")
                            }
                            SupplicantState.FOUR_WAY_HANDSHAKE -> {
                                Log.d(TAG, "正在进行四次握手...")
                            }
                            SupplicantState.COMPLETED -> {
                                Log.d(TAG, "连接完成")
                            }
                            else -> {
                                Log.d(TAG, "其他状态: $state")
                            }
                        }
                    }
                }
            }
        }

        // 注册接收器
        val filter = IntentFilter().apply {
            addAction(NETWORK_STATE_CHANGED_ACTION)
            addAction(SUPPLICANT_STATE_CHANGED_ACTION)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                addAction(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)
            }
        }
        context.registerReceiver(receiver, filter)
        Log.d(TAG, "已注册网络状态监听器")

        // 设置超时
        handler.postDelayed({
            if (!isConnected) {
                Log.e(TAG, "连接超时")
                context.unregisterReceiver(receiver)
                continuation.resume(false)
            }
        }, 10000) // 10秒超时
    }

    private fun connectWithSuggestion(ssid: String, password: String): Boolean {
        Log.d(TAG, "使用WifiNetworkSuggestion方式连接")
        val suggestion = WifiNetworkSuggestion.Builder()
            .setSsid(ssid)
            .setWpa2Passphrase(password)
            .setIsAppInteractionRequired(true)
            .build()

        val suggestions = listOf(suggestion)
        val status = wifiManager.addNetworkSuggestions(suggestions)
        
        return when (status) {
            WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS -> {
                Log.d(TAG, "网络建议添加成功")
                true
            }
            WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE -> {
                Log.d(TAG, "网络建议已存在")
                true
            }
            else -> {
                Log.e(TAG, "添加网络建议失败,状态码: $status")
                false
            }
        }
    }

    private fun connectWithConfiguration(ssid: String, password: String): Boolean {
        Log.d(TAG, "使用WifiConfiguration方式连接")
        val config = WifiConfiguration().apply {
            SSID = "\"$ssid\""
            preSharedKey = "\"$password\""
            status = WifiConfiguration.Status.ENABLED
            allowedProtocols.clear()
            allowedKeyManagement.clear()
            allowedPairwiseCiphers.clear()
            allowedGroupCiphers.clear()
            
            // 设置WPA2加密
            allowedProtocols.set(WifiConfiguration.Protocol.RSN)
            allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
            allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
            allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
        }

        val netId = wifiManager.addNetwork(config)
        if (netId == -1) {
            Log.e(TAG, "添加网络配置失败")
            return false
        }
        Log.d(TAG, "网络配置添加成功,netId: $netId")

        val success = wifiManager.enableNetwork(netId, true)
        Log.d(TAG, "启用网络结果: $success")
        return success
    }
} 

\app\src\main\java\com\example\qs_wifi\MainActivity.kt

MainActivity.kt

// MainActivity.kt
package com.example.qs_wifi

import android.Manifest
import android.content.*
import android.content.pm.PackageManager
import android.net.wifi.ScanResult
import android.net.wifi.WifiManager
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.qs_wifi.databinding.ActivityMainBinding
import com.example.qs_wifi.databinding.DialogConnectWifiBinding
import com.example.qs_wifi.databinding.DialogProgressBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class MainActivity : AppCompatActivity() {
    private val TAG = "MainActivity"
    private lateinit var binding: ActivityMainBinding
    private lateinit var wifiManager: WifiManager
    private lateinit var wifiConnectionManager: WifiConnectionManager
    private lateinit var wifiAdapter: WifiAdapter
    private var isScanning = false
    private var progressDialog: AlertDialog? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d(TAG, "=== 应用启动 ===")
        
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager
        wifiConnectionManager = WifiConnectionManager(this)
        Log.d(TAG, "WiFi管理器初始化完成")

        setupUI()
        checkPermissions()
    }

    private fun setupUI() {
        Log.d(TAG, "设置UI组件")
        binding.wifiList.layoutManager = LinearLayoutManager(this)
        wifiAdapter = WifiAdapter { wifiItem ->
            Log.d(TAG, "用户点击WiFi: ${wifiItem.ssid}")
            showConnectDialog(wifiItem)
        }
        binding.wifiList.adapter = wifiAdapter

        binding.swipeRefresh.setOnRefreshListener {
            Log.d(TAG, "用户触发刷新")
            startWifiScan()
        }

        binding.fabScan.setOnClickListener {
            Log.d(TAG, "用户点击扫描按钮")
            startWifiScan()
        }
    }

    private fun showConnectDialog(wifiItem: WifiItem) {
        Log.d(TAG, "显示连接对话框: ${wifiItem.ssid}")
        if (wifiItem.isConnected) {
            Log.d(TAG, "网络已连接,无需操作")
            return
        }

        val dialogBinding = DialogConnectWifiBinding.inflate(layoutInflater)
        val dialog = MaterialAlertDialogBuilder(this)
            .setTitle("连接 ${wifiItem.ssid}")
            .setView(dialogBinding.root)
            .setPositiveButton("连接") { dialog, _ ->
                val password = dialogBinding.passwordInput.text.toString()
                Log.d(TAG, "用户输入密码,长度: ${password.length}")
                connectToWifi(wifiItem.ssid, password)
                dialog.dismiss()
            }
            .setNegativeButton("取消", null)
            .create()

        dialog.show()
    }

    private fun connectToWifi(ssid: String, password: String) {
        Log.d(TAG, "开始连接WiFi: $ssid")
        showProgressDialog("正在连接...")
        
        lifecycleScope.launch {
            try {
                val success = wifiConnectionManager.connectToWifi(ssid, password)
                Log.d(TAG, "连接结果: $success")
                
                withContext(Dispatchers.Main) {
                    progressDialog?.dismiss()
                    if (success) {
                        showToast("连接成功")
                        startWifiScan() // 刷新列表
                    } else {
                        showToast("连接失败,请检查密码")
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "连接过程发生异常", e)
                withContext(Dispatchers.Main) {
                    progressDialog?.dismiss()
                    showToast("连接失败: ${e.message}")
                }
            }
        }
    }

    private fun startWifiScan() {
        if (isScanning) {
            Log.d(TAG, "扫描正在进行中,忽略请求")
            return
        }

        Log.d(TAG, "开始WiFi扫描")
        isScanning = true
        binding.swipeRefresh.isRefreshing = true
        binding.fabScan.isEnabled = false

        wifiManager.startScan()
        registerReceiver(wifiScanReceiver, IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
    }

    private val wifiScanReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            Log.d(TAG, "收到扫描结果广播")
            if (intent.action == WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) {
                context.unregisterReceiver(this)
                handleScanResults()
            }
        }
    }

    private fun handleScanResults() {
        Log.d(TAG, "处理扫描结果")
        try {
            val results = wifiManager.scanResults
            Log.d(TAG, "扫描到 ${results.size} 个网络")

            // 获取当前连接的网络
            val currentWifi = wifiManager.connectionInfo
            val currentSsid = currentWifi?.ssid?.removeSurrounding("\"")
            Log.d(TAG, "当前连接的网络: $currentSsid")

            // 获取已保存的网络列表
            val savedNetworks = wifiManager.configuredNetworks
            val savedSsids = savedNetworks?.map { it.SSID.removeSurrounding("\"") } ?: emptyList()
            Log.d(TAG, "已保存的网络: $savedSsids")

            // 处理扫描结果
            val wifiItems: List<WifiItem> = results
                .filter { it.SSID.isNotEmpty() }
                .groupBy { it.SSID }
                .mapNotNull { (ssid, networks) ->
                    networks.maxByOrNull { it.level }?.let { bestNetwork ->
                        val signalStrength = WifiManager.calculateSignalLevel(bestNetwork.level, 100)
                        val isSecure = bestNetwork.capabilities.contains("WPA") || 
                                     bestNetwork.capabilities.contains("WPA2") ||
                                     bestNetwork.capabilities.contains("WPA3") ||
                                     bestNetwork.capabilities.contains("WEP")
                        
                        WifiItem(
                            ssid = ssid,
                            signalStrength = signalStrength,
                            isSecure = isSecure,
                            isSaved = savedSsids.contains(ssid),
                            isConnected = ssid == currentSsid
                        )
                    }
                }
                .sortedByDescending { it.signalStrength }

            Log.d(TAG, "处理后的网络列表大小: ${wifiItems.size}")
            wifiAdapter.updateWifiList(wifiItems)
        } catch (e: Exception) {
            Log.e(TAG, "处理扫描结果时发生错误", e)
        } finally {
            isScanning = false
            binding.swipeRefresh.isRefreshing = false
            binding.fabScan.isEnabled = true
        }
    }

    private fun showProgressDialog(message: String) {
        Log.d(TAG, "显示进度对话框: $message")
        val dialogBinding = DialogProgressBinding.inflate(layoutInflater)
        dialogBinding.message.text = message

        progressDialog = MaterialAlertDialogBuilder(this)
            .setView(dialogBinding.root)
            .setCancelable(false)
            .create()

        progressDialog?.show()
    }

    private fun showToast(message: String) {
        Log.d(TAG, "显示Toast: $message")
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }

    private fun checkPermissions() {
        if (hasRequiredPermissions()) {
            startWifiScan()
        } else {
            requestPermissions()
        }
    }

    private fun hasRequiredPermissions(): Boolean {
        return REQUIRED_PERMISSIONS.all {
            ActivityCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
        }
    }

    private fun requestPermissions() {
        ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, PERMISSIONS_REQUEST_CODE)
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == PERMISSIONS_REQUEST_CODE) {
            if (grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
                startWifiScan()
            } else {
                Toast.makeText(this, "需要位置权限才能扫描WiFi", Toast.LENGTH_SHORT).show()
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        try {
            unregisterReceiver(wifiScanReceiver)
        } catch (e: Exception) {
            Log.e(TAG, "取消注册接收器失败", e)
        }
        progressDialog?.dismiss()
    }

    companion object {
        private const val PERMISSIONS_REQUEST_CODE = 101
        private val REQUIRED_PERMISSIONS = arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    }
}

\app\src\main\java\com\example\qs_wifi\WifiItem.kt

WifiItem.kt

package com.example.qs_wifi

data class WifiItem(
    val ssid: String,
    val signalStrength: Int,
    val isSecure: Boolean,
    val isSaved: Boolean,
    val isConnected: Boolean
) {
    companion object {
        fun fromScanResult(result: android.net.wifi.ScanResult, isConnected: Boolean, isSaved: Boolean): WifiItem {
            val signalStrength = android.net.wifi.WifiManager.calculateSignalLevel(result.level, 100)
            val isSecure = result.capabilities.contains("WPA") || 
                          result.capabilities.contains("WPA2") ||
                          result.capabilities.contains("WPA3") ||
                          result.capabilities.contains("WEP")
            
            return WifiItem(
                ssid = result.SSID,
                signalStrength = signalStrength,
                isSecure = isSecure,
                isSaved = isSaved,
                isConnected = isConnected
            )
        }
    }
} 
本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值