Android 扫描WIFI权限详解

权限

上篇文章 Android 获取IP和UA中提及了获取WIFI的IP地址,本篇文章介绍下如何扫描WIFI。

官方文档

根据官方文档描述,扫描WIFI需要申请相关权限,如下:

Android 13以上



    
    
    
    

Android 13以下



    
    
    

需要注意,在实际测试中,Android 13以上的设备仍然需要申请android.permission.ACCESS_FINE_LOCATION才能扫描到WIFI,测试设备为小米13。

注册广播监听扫描状态

通过注册广播监听WIFI扫描是否完成,代码如下:

class WIFIExampleActivity : AppCompatActivity() {
    private val scanResultReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent?.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false) == true) {
                // 扫描完成
            }
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 注册广播
        registerReceiver(scanResultReceiver, IntentFilter().apply {
            addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
        })
    }
    override fun onDestroy() {
        super.onDestroy()
        // 移除广播
        unregisterReceiver(scanResultReceiver)
    }
}

扫描WIFI

通过WifiManager扫描WIFI,并获取扫描结果,代码如下:

// 列表适配器
class WIFIAdapter : RecyclerView.Adapter() {
    private val wifiData = ArrayList()
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WIFIViewHolder {
        return WIFIViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_wifi_item, parent, false))
    }
    override fun onBindViewHolder(holder: WIFIViewHolder, position: Int) {
        wifiData[position].run {
            holder.tvWifiName.text = wifiSSID
            holder.tvWifiSSID.text = wifiBSSID
            holder.ivWifiStrength.setImageResource(getStrengthIcon(wifiStrength))
            holder.ivNeedPassword.setImageResource(if (needPassword) R.drawable.icon_lock else R.drawable.icon_unlock)
        }
    }
    override fun getItemCount(): Int {
        return wifiData.size
    }
    fun setNewData(wifiData: ArrayList?) {
        val lastItemCount = itemCount
        if (lastItemCount != 0) {
            this.wifiData.clear()
            notifyItemRangeRemoved(0, lastItemCount)
        }
        wifiData?.let { this.wifiData.addAll(it) }
        notifyItemChanged(0, itemCount)
    }
    private fun getStrengthIcon(wifiStrength: Int): Int {
        return when (wifiStrength) {
            0 -> R.drawable.wifi_strength_0
            1 -> R.drawable.wifi_strength_1
            2 -> R.drawable.wifi_strength_2
            else -> R.drawable.wifi_strength_3
        }
    }
    interface ItemClickListener {
        fun onItemClick(wifiInfo: WIFIEntity)
    }
    class WIFIViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val tvWifiName: AppCompatTextView = itemView.findViewById(R.id.tv_wifi_name)
        val tvWifiSSID: AppCompatTextView = itemView.findViewById(R.id.tv_wifi_ssid)
        val ivNeedPassword: AppCompatImageView = itemView.findViewById(R.id.iv_need_password)
        val ivWifiStrength: AppCompatImageView = itemView.findViewById(R.id.iv_wifi_strength)
    }
}
class WIFIExampleActivity : AppCompatActivity() {
    private lateinit var binding: LayoutWifiExampleActivityBinding
    private val wifiAdapter = WIFIAdapter()
    private var wifiManager: WifiManager? = null
    private var requestPermissionName: String = Manifest.permission.ACCESS_FINE_LOCATION
    private val requestSinglePermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted: Boolean ->
        if (granted) {
            // 申请定位权限通过,扫描WIFI
            if (wifiManager?.isWifiEnabled == true) {
                wifiManager?.startScan()
            }
        } else {
            //未同意授权
            if (!shouldShowRequestPermissionRationale(requestPermissionName)) {
                //用户拒绝权限并且系统不再弹出请求权限的弹窗
                //这时需要我们自己处理,比如自定义弹窗告知用户为何必须要申请这个权限
            }
        }
    }
    private val scanResultReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent?.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false) == true) {
                val wifiData = ArrayList()
                wifiManager?.scanResults?.forEach {
                    val ssid = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                        it.wifiSsid.toString()
                    } else {
                        it.SSID
                    }
                    val bssid = it.BSSID
                    // 获取WIFI加密类型
                    val capabilities = it.capabilities
                    // 获取WIFI信号强度
                    val level = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                        wifiManager?.calculateSignalLevel(it.level) ?: 0
                    } else {
                        WifiManager.calculateSignalLevel(it.level, 4)
                    }
                    wifiData.add(WIFIEntity(ssid, bssid, capabilities.contains("wpa", true) || capabilities.contains("web", true), capabilities, level))
                }
                // 根据信号强度降序排列
                wifiData.sortByDescending { it.wifiStrength }
                wifiAdapter.setNewData(wifiData)
            }
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.layout_wifi_example_activity)
        wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        binding.includeTitle.tvTitle.text = "WIFI Example"
        binding.btnStartScan.setOnClickListener {
            // 检测定位权限
            if (ActivityCompat.checkSelfPermission(this, requestPermissionName) == PackageManager.PERMISSION_GRANTED) {
                if (wifiManager?.isWifiEnabled == true) {
                    wifiManager?.startScan()
                }
            } else {
                requestSinglePermissionLauncher.launch(requestPermissionName)
            }
        }
        binding.rvWifiInfo.adapter = wifiAdapter
        registerReceiver(scanResultReceiver, IntentFilter().apply {
            addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
        })
    }
    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(scanResultReceiver)
    }
}

效果如图:

示例

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

ExampleDemo github

ExampleDemo gitee

以上就是Android 扫描WIFI权限详解的详细内容,更多关于Android 扫描WIFI权限的资料请关注脚本之家其它相关文章!

你可能感兴趣的:(Android 扫描WIFI权限详解)